2014-03-02 66 views

回答

4

bitcoin_address_validator.rb從GitHub檢查一個比特幣地址是有效的:

require 'digest' 

class BitcoinAddressValidator < ActiveModel::EachValidator 
    def validate(record, field, value) 
    unless valid_bitcoin_address?(value) 
     record.errors[field] << "Bitcoin address is invalid" 
    end 
    end 

    private 

    B58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' 
    B58Base = B58Chars.length 

    def self.valid_bitcoin_address?(address) 
    (address =~ /^[a-zA-Z1-9]{33,35}$/) and version(address) 
    end 

    def self.version(address) 
    decoded = b58_decode(address, 25) 

    version = decoded[0, 1] 
    checksum = decoded[-4, decoded.length] 
    vh160 = decoded[0, decoded.length - 4] 

    hashed = (Digest::SHA2.new << (Digest::SHA2.new << vh160).digest).digest 

    hashed[0, 4] == checksum ? version[0] : nil 
    end 

    def self.b58_decode(value, length) 
    long_value = 0 
    index = 0 
    result = "" 

    value.reverse.each_char do |c| 
     long_value += B58Chars.index(c) * (B58Base ** index) 
     index += 1 
    end 

    while long_value >= 256 do 
     div, mod = long_value.divmod 256 
     result = mod.chr + result 
     long_value = div 
    end 

    result = long_value.chr + result 

    if result.length < length 
     result = 0.chr * (length - result.length) + result 
    end 

    result 
    end 
end 

通行證單元測試(見http://github.com/davout/bitcoin-bank

並檢查格式

class User < ActiveRecord::Base 
    validates :bitcoin_address, format: { with: /\A(1|3)[a-zA-Z1-9]{26,33}\z/, 
    message: "invalid bitcoin address" } 
    # This is NOT calculate checksum 
end 
5

如果你不」要保持自己的實現,可以使用the bitcoin-ruby gem

具體爲:Bitcoin.valid_address? "your_address_here"

相關問題