Ropsten

使用 Web3.py 部署合約後的事務雜湊太長

  • February 1, 2022

我使用這段程式碼成功地將使用 Web3.py 的合約部署到乙太坊 Ropsten 網路

def deploy(self):
   instance = self.w3.eth.contract(abi=self.abi, bytecode=self.bin)

   construct_txn = instance.constructor().buildTransaction({
       'from': self.pub,
       'value': 10,
       'gas': 1000000,
       'gasPrice': w3.eth.gasPrice,
       'nonce': self.w3.eth.getTransactionCount(self.pub),
   })

   signed = self.acct.signTransaction(construct_txn)
   tx_hash = self.w3.eth.sendRawTransaction(signed.rawTransaction)
   print(tx_hash.hex())

然後我獲取交易雜湊,並將其傳遞給這個函式來創建一個我可以使用 Python 玩弄的合約實例

def contract_in_concise_mode(contract_address):
   # Contract instance in concise mode
   abi = contract_interface['abi']
   contract_instance = w3.eth.contract(address=contract_address, abi=abi, ContractFactoryClass=ConciseContract)
   return contract_instance

但我收到了這個錯誤

web3.exceptions.InvalidAddress: ('Address must be 20 bytes, as a hex string with a 0x prefix', '0xa ....... 49')

sendRawTransaction 返回一個交易雜湊,你需要合約地址。交易雜湊是 32 字節,地址是 20 字節。

要獲得地址,您必須檢查交易收據。

來自 web3.py 文件https://web3py.readthedocs.io/en/stable/contracts.html

# Wait for the transaction to be mined, and get the transaction receipt
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)

# Create the contract instance with the newly-deployed address
greeter = w3.eth.contract(
   address=tx_receipt.contractAddress,
   abi=contract_interface['abi'],
)

函式sendRawTransaction返回交易雜湊而不是智能合約地址。為了獲得智能合約地址,您基本上有兩種選擇:

  1. 正如@Ismael 建議的那樣,等到交易被探勘,獲取其收據並從中提取合約地址
  2. from從地址和 nonce 值導出智能合約地址

對於第一種方法,請執行以下操作:

contract_address = web3.eth.getTransactionReceipt(tx_hash)['contractAddress']

請參閱Web3.py 文件中的詳細資訊

對於第二種方法,請執行以下操作:

contract_address = sha3(rlp.encode([normalize_address(sender), nonce]))[12:]

對於秒的方式,您不需要等到您的交易被探勘。有關如何派生合約地址的詳細資訊,請參閱此答案

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