Solidity

如何使用 EthereumTesterProvider 發送代幣?

  • May 18, 2018

我有一個如下的堅固契約:

合約 MyToken {
字元串公共符號;
字元串公共名稱;
uint8 公共小數;
uint public _totalSupply;

映射(地址 => uint)餘額;
映射(地址 => 映射(地址 => uint))允許;


建構子(){
符號=“我的”;
name = "我的令牌";
小數 = 18;
_totalSupply = 100000000000000000000000000;

餘額[0x364ca3F935E88Fbc9e041d2032F996CAc69452e6] = _totalSupply / 2;
餘額[0x5506195d8111B5e150Fb68Ceba2806c546C5a28B] = _totalSupply / 2;

轉賬(地址(0),0x364ca3F935E88Fbc9e041d2032F996CAc69452e6,
_totalSupply / 2);
轉賬(地址(0),0x55​​06195d8111B5e150Fb68Ceba2806c546C5a28B,
_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_pa​​rams)
中間件中的文件“/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_pa​​rams)
中間件中的文件“/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_pa​​rams)
中間件中的文件“/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py”,第 21 行
response = make_request(方法,formatted_pa​​rams)
中間件中的文件“/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_pa​​rams)
文件“/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。它是最積極維護的。不過,它們通常都應該工作。

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