Python

我怎樣才能簡單地簽署乙太坊交易?

  • June 13, 2018

我想使用blockcypher來處理乙太坊網路。

文件中,他們給出了一個用 Go 編寫的簽名工具的範例,但我使用的是 Python。

簽署交易的最簡單方法是什麼?

我嘗試使用web3.py,但遇到了一些困難。

在這裡,他們給出了以下範例:

transaction = {
      'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
      'value': 1000000000,
      'gas': 2000000,
      'gasPrice': 234567897654321,
      'nonce': 0,
      'chainId': 1
}
key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
signed = w3.eth.account.signTransaction(transaction, key)
signed.rawTransaction
HexBytes('0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428')
signed.hash
HexBytes('0xd8f64a42b57be0d565f385378db2f6bf324ce14a594afc05de90436e9ce01f60')
signed.r
4487286261793418179817841024889747115779324305375823110249149479905075174044
signed.s
30785525769477805655994251009256770582792548537338581640010273753578382951464
signed.v
37

但是我不明白一些需要傳遞給transaction.

什麼是noncechainId

使用此類數據:

transaction = {
   'to': '0xe980e77404ae62ab0f2d6b8510bd951e25185414',
   'value': value,
   'gas': 2000000,
   'gasPrice': 1000000000,,
   'nonce': 0,
   'chainId': 1
}

我收到此錯誤:

TypeError: Transaction had invalid fields: {'to': '0xe980e77404ae62ab0f2d6b8510bd951e25185414'}

接下來,我嘗試使用ecdsa

但我找不到一個簡單的例子。我對密碼學一無所知,我需要最簡單的方法將交易發送到網路,而無需仔細研究細節。

更新

我盡量避免使用 w3,因為我只需要簽署一個交易。

我能夠這樣做來創建簽名:

導入 hashlib 導入 binascii

進口ecdsa

def sign(privkey, message):
   sk = ecdsa.SigningKey.from_string(
       binascii.unhexlify(privkey),
       curve=ecdsa.SECP256k1,
       hashfunc=hashlib.sha256
   )
   signature = binascii.hexlify(
       sk.sign(
           binascii.unhexlify(message),
           hashfunc=hashlib.sha256
       )
   )
   return signature

該函式工作正常,我返回一個像這樣的字節字元串:

b'4ace74a83082b5fc6d356083932b493e9fafbe0fabca19be3e77ccda188d08c6352f1fccb144e18b95a3f7e18f71fe95d79a9dd8ad9ecaa7490315f06a00177f'

但是這一行的長度是 128 個字元,在 blockcypher 的例子中是一個 148 個字元的字元串。

在嘗試向網路發送簽名交易後,我收到這樣的回复:

{'error': 'Could not compute an address from provided signature: invalid transaction v, r, s values.'}

很可能,我創建了錯誤的簽名,但是如何製作正確的簽名呢?

看來我快到了,但仍然沒有成功。

web3.py 4.x 版要求所有地址使用正確的EIP 55 校驗和。在我的測試中,我收到與您相同的錯誤,直到我將地址轉換為正確的校驗和形式(注意大寫):

0xe980E77404ae62aB0F2d6b8510BD951e25185414

(請注意,您還有一個額外的逗號使您的程式碼在語法上無效,但我認為這只是一個複制/粘貼錯誤。)

感謝@smarx 的提示。

但是,我設法找到了另一種解決方案:

from bitcoin import ecdsa_raw_sign
from bitcoin import der_encode_sig

def signing(transaction, privkey):
   signature = der_encode_sig(*ecdsa_raw_sign(transaction, privkey))
   return signature

引用自:https://ethereum.stackexchange.com/questions/51148