Solidity
如何使用 EthereumTesterProvider 發送代幣?
我有一個如下的堅固契約:
合約 MyToken { 字元串公共符號; 字元串公共名稱; uint8 公共小數; uint public _totalSupply; 映射(地址 => uint)餘額; 映射(地址 => 映射(地址 => uint))允許; 建構子(){ 符號=“我的”; name = "我的令牌"; 小數 = 18; _totalSupply = 100000000000000000000000000; 餘額[0x364ca3F935E88Fbc9e041d2032F996CAc69452e6] = _totalSupply / 2; 餘額[0x5506195d8111B5e150Fb68Ceba2806c546C5a28B] = _totalSupply / 2; 轉賬(地址(0),0x364ca3F935E88Fbc9e041d2032F996CAc69452e6, _totalSupply / 2); 轉賬(地址(0),0x5506195d8111B5e150Fb68Ceba2806c546C5a28B, _totalSupply / 2); } // ------------------------------------------------------------------------ // 將餘額從代幣所有者的賬戶轉移到賬戶 // - 所有者的賬戶必須有足夠的餘額才能轉賬 // - 允許 0 值傳輸 // ------------------------------------------------------------------------ function transfer(address to, uint tokens) public 返回 (bool success) { // 為了最小的例子,這是不安全的 餘額[msg.sender] -= 代幣; 餘額[to] += 代幣; 轉移(msg.sender,to,tokens); 返回真; } }
我正在使用 web3py 對此合約進行測試,但我無法將硬幣從
0x5506195d8111B5e150Fb68Ceba2806c546C5a28B
我在測試中聲明的虛擬地址轉移。我的測試如下:導入 web3 導入單元測試 類TestMycroToken(unittest.TestCase): 預設設置(自我): self.w3 = web3.Web3(web3.EthereumTesterProvider()) self.contract, self.contract_address, self.contract_instance = self.deploy_contract() def deploy_contract(): 已編譯溶膠 = 編譯文件([]) contract_interface = compiled_sol[f'{PATH_TO_MY_CONTRACT}:MyToken'] # 實例化和部署合約 合約 = self.w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin']) # 從已部署的合約中獲取交易雜湊 tx_hash = contract.constructor().transact({'from': self.w3.eth.accounts[0]}) # 獲取 tx 收據以獲取合約地址 tx_receipt = self.w3.eth.getTransactionReceipt(tx_hash) contract_address = tx_receipt['contractAddress'] # 簡潔模式下的合約實例 abi = contract_interface['abi'] contract_instance = self.w3.eth.contract(address=contract_address, abi=abi, ContractFactoryClass=web3.contract.ConciseContract) 返回合約,contract_address,contract_instance def test_transfer(self): DUMMY_USER = "0x111111111111111111111111111111111111112" USER_ADDRESS = "0x5506195d8111B5e150Fb68Ceba2806c546C5a28B" # 這行失敗 self.contract_instance.transfer(DEFAULT_USER, 10, 交易={'from': USER_ADDRESS})
當我嘗試從
USER_ADDRESS
(在建構子期間向他們發送硬幣的人)轉移硬幣時,我遇到以下失敗:錯誤 回溯(最近一次通話最後): _send_evm_transaction 中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py”,第 137 行 發件人 = tester.keys[tester.accounts.index(transaction['from'])] ValueError: b'U\x06\x19]\x81\x11\xb5\xe1P\xfbh\xce\xba(\x06\xc5F\xc5\xa2\x8b' 不在列表中 在處理上述異常的過程中,又出現了一個異常: 回溯(最近一次通話最後): testPartExecutor 中的文件“/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py”,第 59 行 屈服 執行中的文件“/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py”,第 605 行 測試方法() 文件“/Users/paymahn/mycro/tests/test_mycro_token.py”,第 129 行,在 test_vote_then_move_balance_is_useless self.contract_instance.transfer(DEFAULT_USER, 10, 交易={'from': AARON_ADDRESS}) __call__ 中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py”,第 777 行 return self.__prepared_function(*args, **kwargs) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py”,第 790 行,在 __prepared_function 返回 getattr(self._function(*args), 修飾符)(modifier_dict) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py”,第 1028 行,在事務中 **self.kwargs) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py”,第 1305 行,在 transact_with_contract_function txn_hash = web3.eth.sendTransaction(transact_transaction) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py”,第 247 行,在 sendTransaction get_buffered_gas_estimate(self.web3, transaction), 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/utils/transactions.py”,第 72 行,在 get_buffered_gas_estimate gas_estimate = web3.eth.estimateGas(gas_estimate_transaction) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py”,第288行,在estimateGas中 [交易], 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py”,第 103 行,在 request_blocking 響應 = self._make_request(方法,參數) _make_request 中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py”,第 86 行 返回請求函式(方法,參數) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/gas_price_strategy.py”,第 18 行 返回 make_request(方法,參數) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py”,第 21 行 response = make_request(方法,formatted_params) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/attrdict.py”,第 18 行 響應 = make_request(方法,參數) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py”,第 21 行 response = make_request(方法,formatted_params) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/normalize_errors.py”,第 9 行 結果 = make_request(方法,參數) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/validation.py”,第 44 行 返回 make_request(方法,post_validated_params) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py”,第 21 行 response = make_request(方法,formatted_params) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/middleware.py”,第 315 行 返回 make_request(方法,[填充交易] + 參數 [1:]) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/fixture.py”,第 12 行 返回 make_request(方法,參數) 中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py”,第 21 行 response = make_request(方法,formatted_params) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/main.py”,第 46 行,在 make_request 響應 = 委託人(self.ethereum_tester,參數) 文件“cytoolz/functoolz.pyx”,第 232 行,在 cytoolz.functoolz.curry.__call__ 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/defaults.py”,第 36 行,在 call_eth_tester 返回 getattr(eth_tester, fn_name)(*fn_args, **fn_kwargs) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/main.py”,第466行,在estimate_gas中 raw_gas_estimate = self.backend.estimate_gas(raw_transaction) 包裝器中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/utils/formatting.py”,第 85 行 返回 to_wrap(*args, **kwargs) 文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py”,第439行,在estimate_gas中 交易=交易, _estimate_evm_transaction 中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py”,第 157 行 return _send_evm_transaction(tester_module, evm, transaction_for_estimate) _send_evm_transaction 中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py”,第 139 行 發件人 = evm.extra_accounts[交易['來自']] KeyError: b'U\x06\x19]\x81\x11\xb5\xe1P\xfbh\xce\xba(\x06\xc5F\xc5\xa2\x8b'
這對我來說很有意義,
USER_ADDRESS
從未在測試提供者中註冊為發件人(我確定我的某些術語有誤)。在deploy_contract
函式中,我從self.w3.eth.accounts[0]
.我的問題是:如何從初始化期間獲得硬幣的地址以 web3py 發送貨幣?
也許您最好的選擇是將地址作為參數傳遞給建構子。然後在測試期間,您可以
w3.eth.accounts[1]
作為帳戶發送到預充值。就像是:constructor(address recipient1, address recipient2) { symbol = "my"; name = "My Token"; decimals = 18; _totalSupply = 100000000000000000000000000; balances[recipient1] = _totalSupply / 2; balances[recipient2] = _totalSupply / 2; Transfer(address(0), recipient1, _totalSupply / 2); Transfer(address(0), recipient2, _totalSupply / 2); }
然後,您可以使用以下命令部署合約:
tx_hash = contract.constructor( w3.eth.accounts[1], w3.eth.accounts[2], ).transact({'from': self.w3.eth.accounts[0]})
旁注:用於 eth-tester 的最佳後端可能就是那個
py-evm
。它是最積極維護的。不過,它們通常都應該工作。