Raw-Transaction

在創建 scriptSig 時,我如何簽署原始交易的雜湊?

  • January 12, 2017

我已經創建了一個原始交易,添加了雜湊碼,然後 Double-sha256 這個結果。現在我應該用私鑰簽署這個散列,這會給我 DER 編碼的簽名,但我不清楚我到底應該做什麼。如何使用私鑰簽署此雜湊**?**我到底要做什麼?除了 SHA256,我沒有使用任何加密庫,並且我自己實現了 secp256k1,所以我想與此相關,我應該如何處理私鑰和雜湊?我專門針對第15步。 如果我猜的話,這個這個基本上是我的答案,除非我弄錯了,如果我是,我想知道為什麼。否則,這些答案的警告是引入隨機隨機數。為什麼我不能只擁有私鑰 =“k”(因為無論如何你都不應該重用地址,對嗎?),計算“s”,並連接“r”和“s”?或者這是如何完成的?

這將是我正在尋找的答案,第一個函式(簽名生成算法)有一個幫助連結,第二個函式有一個幫助連結(用於生成“k”的 rfc6979 標準)

def ecdsa_sign(val, secret_exponent):
   """Return a signature for the provided hash, using the provided
   random nonce. It is absolutely vital that random_k be an unpredictable
   number in the range [1, self.public_key.point.order()-1].  If
   an attacker can guess random_k, he can compute our private key from a
   single signature. Also, if an attacker knows a few high-order
   bits (or a few low-order bits) of random_k, he can compute our private
   key from many signatures. The generation of nonces with adequate
   cryptographic strength is very difficult and far beyond the scope
   of this comment.

   May raise RuntimeError, in which case retrying with a new
   random value k is in order.
   """
   G = ecdsa.SECP256k1
   n = G.order()
   k = deterministic_generate_k(n, secret_exponent, val)
   p1 = k * G
   r = p1.x()
   if r == 0: raise RuntimeError("amazingly unlucky random number r")
   s = ( ecdsa.numbertheory.inverse_mod( k, n ) * ( val + ( secret_exponent * r ) % n ) ) % n
   if s == 0: raise RuntimeError("amazingly unlucky random number s")

   return signature_to_der(r, s)

def deterministic_generate_k(generator_order, secret_exponent, val, hash_f=hashlib.sha256):
   """
   Generate K value according to https://www.rfc-editor.org/rfc/rfc6979
   """
   n = generator_order
   order_size = (bit_length(n) + 7) // 8
   hash_size = hash_f().digest_size
   v = b'\x01' * hash_size
   k = b'\x00' * hash_size
   priv = intbytes.to_bytes(secret_exponent, length=order_size)
   shift = 8 * hash_size - bit_length(n)
   if shift > 0:
       val >>= shift
   if val > n:
       val -= n
   h1 = intbytes.to_bytes(val, length=order_size)
   k = hmac.new(k, v + b'\x00' + priv + h1, hash_f).digest()
   v = hmac.new(k, v, hash_f).digest()
   k = hmac.new(k, v + b'\x01' + priv + h1, hash_f).digest()
   v = hmac.new(k, v, hash_f).digest()

   while 1:
       t = bytearray()

       while len(t) < order_size:
            v = hmac.new(k, v, hash_f).digest()
            t.extend(v)

       k1 = intbytes.from_bytes(bytes(t))

       k1 >>= (len(t)*8 - bit_length(n))
       if k1 >= 1 and k1 < n:
           return k1

       k = hmac.new(k, v + b'\x00', hash_f).digest()
       v = hmac.new(k, v, hash_f).digest()

這不是sha256(sha256(tx_bytes))需要簽名的。您需要遵循比特幣核心內部定義的特定算法來生成正確的數字簽名。這裡是定義簽名編碼算法的地方。請注意,此算法會根據hash type您提供的內容略有變化。這允許我們在交易中包含(或阻止包含)額外輸入/輸出的功能。

引用自:https://bitcoin.stackexchange.com/questions/50727