EthWorks / ethereum.rb

Ethereum library for the Ruby language
MIT License
731 stars 229 forks source link

trying to use non-default sender to approve funds to transfer on ERC20 contract #159

Closed tansaku closed 3 years ago

tansaku commented 3 years ago

so I was reading https://github.com/EthWorks/ethereum.rb/issues/59#issuecomment-369543139 about how to set a non-default sender for a contract operation

Steps to reproduce

contract.sender = account2
contract.call.approve(account2, 100) 
contract.call.increase_allowance(account2, 100) 
contract.call.transfer_from(account2, account1, 10)

Expected behavior

funds should be transfered

Actual behavior

IOError: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance from /Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/client.rb:129:in `send_command'

System configuration

Ruby version:2.7.2 Solc version: Parity version: OS: OSX 11.5

Failure Logs

Here's my stack trace:

I, [2021-07-23T15:44:54.856165 #52495]  INFO -- IOError: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance
I, [2021-07-23T15:44:54.856305 #52495]  INFO -- IOError: /Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/client.rb:129:in `send_command'
/Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
/Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:173:in `call_raw'
/Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:179:in `call'
/Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:322:in `block (2 levels) in create_function_proxies'

and the underlying eth log

# Logfile created on 2021-07-23 15:44:38 +0000 by logger.rb/v1.4.2
I, [2021-07-23T15:44:40.487743 #52495]  INFO -- : Sending {"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}
I, [2021-07-23T15:44:40.501032 #52495]  INFO -- : Received {"id":1,"jsonrpc":"2.0","result":["0x3ab2d5f13a9c08ec80e71188a8922eeffbf5331f","0x624d35bb1f9f2964ab0a6b37c691141063489ffd","0x7e1d18968c341af870c4412a253459327addde80","0x37621b0f2812e1b5abe7e5c431985678f8f494bd","0x423d5da8e64430e4d19eae7875748c0e1550f29e","0xf2d9075de5f9531098854d73a87d94f4f0878745","0x0338b6b98054271203589883f040b72bc54f7896","0xa3182688498d00793cd0e43de74a1ac0c2c81d27","0x8407b00cb1fa306d3ab55a99a0d00027653a6dcf","0x84f955eed96548753b4690a29999fe1c1ff4a9c2"]}
I, [2021-07-23T15:44:43.761945 #52495]  INFO -- : Sending {"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x012dd0b4a469D95eB07aC7d63F5a7590082F7D96","from":"0x624D35BB1f9f2964Ab0A6b37c691141063489ffD","data":"0x095ea7b3000000000000000000000000624D35BB1f9f2964Ab0A6b37c691141063489ffD0000000000000000000000000000000000000000000000000000000000000071","gas":"0x3d0900","gasPrice":"0x51f4d5c00"},"latest"],"id":1}
I, [2021-07-23T15:44:43.782949 #52495]  INFO -- : Received {"id":1,"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000001"}
I, [2021-07-23T15:44:46.112413 #52495]  INFO -- : Sending {"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x012dd0b4a469D95eB07aC7d63F5a7590082F7D96","from":"0x624D35BB1f9f2964Ab0A6b37c691141063489ffD","data":"0x39509351000000000000000000000000624D35BB1f9f2964Ab0A6b37c691141063489ffD0000000000000000000000000000000000000000000000000000000000000071","gas":"0x3d0900","gasPrice":"0x51f4d5c00"},"latest"],"id":1}
I, [2021-07-23T15:44:46.136101 #52495]  INFO -- : Received {"id":1,"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000001"}
I, [2021-07-23T15:44:50.859530 #52495]  INFO -- : Sending {"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x012dd0b4a469D95eB07aC7d63F5a7590082F7D96","from":"0x624D35BB1f9f2964Ab0A6b37c691141063489ffD","data":"0x23b872dd000000000000000000000000624D35BB1f9f2964Ab0A6b37c691141063489ffD0000000000000000000000003aB2D5F13a9c08ec80E71188a8922eeffBF5331f0000000000000000000000000000000000000000000000000000000000000071","gas":"0x3d0900","gasPrice":"0x51f4d5c00"},"latest"],"id":1}
I, [2021-07-23T15:44:50.882173 #52495]  INFO -- : Received {"id":1,"jsonrpc":"2.0","error":{"message":"VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance","code":-32000,"data":{"0x6f93a53184e8c71f8977f4dafb5748601bbd2f69babd2822815cf6c9e704da04":{"error":"revert","program_counter":1127,"return":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002845524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365000000000000000000000000000000000000000000000000","reason":"ERC20: transfer amount exceeds allowance"},"stack":"RuntimeError: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance\n    at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n    at /Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:568:26","name":"RuntimeError"}}}
I, [2021-07-23T15:44:54.819360 #52495]  INFO -- : Sending {"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x012dd0b4a469D95eB07aC7d63F5a7590082F7D96","from":"0x624D35BB1f9f2964Ab0A6b37c691141063489ffD","data":"0x23b872dd000000000000000000000000624D35BB1f9f2964Ab0A6b37c691141063489ffD0000000000000000000000003aB2D5F13a9c08ec80E71188a8922eeffBF5331f0000000000000000000000000000000000000000000000000000000000000071","gas":"0x3d0900","gasPrice":"0x51f4d5c00"},"latest"],"id":1}
I, [2021-07-23T15:44:54.855541 #52495]  INFO -- : Received {"id":1,"jsonrpc":"2.0","error":{"message":"VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance","code":-32000,"data":{"0x6f93a53184e8c71f8977f4dafb5748601bbd2f69babd2822815cf6c9e704da04":{"error":"revert","program_counter":1127,"return":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002845524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365000000000000000000000000000000000000000000000000","reason":"ERC20: transfer amount exceeds allowance"},"stack":"RuntimeError: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance\n    at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n    at /Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:568:26","name":"RuntimeError"}}}
tansaku commented 3 years ago

I've now also tried setting the private key and default account as per the second set of suggestions in https://github.com/EthWorks/ethereum.rb/issues/59#issuecomment-376571671 and that's not working either ... even for a single token:

> client.default_account = account2
> contract.key = Eth::Key.new(priv: your_private_key) 
> contract.call.approve(account2, 1) # returns true
> contract.call.increase_allowance(account2, 1) # returns true
> contract.call.transfer_from(account2, account1, 1)
IOError: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance
from /Users/samueljoseph/.rvm/gems/ruby-2.7.2/gems/ethereum.rb-2.5/lib/ethereum/client.rb:129:in `send_command'
tansaku commented 3 years ago

Also even from a simple transfer which returns true I don't actually see any balance changes:

2.7.2 :021 > contract.call.transfer(account2, 1)
 => true 
2.7.2 :022 > contract.call.balance_of(account1)
 => 99998990 
2.7.2 :023 > contract.call.balance_of(account2)
 => 10 
2.7.2 :024 > contract.call.transfer(account2, 1)
 => true 
2.7.2 :025 > contract.call.balance_of(account2)
 => 10 
2.7.2 :026 > contract.call.balance_of(account1)
 => 99998990 
tansaku commented 3 years ago

doh - I should be using transact_and_wait

tansaku commented 3 years ago
2.7.2 :042 > client.default_account = "0x624D35BB1f9f2964Ab0A6b37c691141063489ffD" 
 => "0x624D35BB1f9f2964Ab0A6b37c691141063489ffD" 
2.7.2 :043 >  contract = Ethereum::Contract.create(client: client, name: "SohoHouseCoin", address: ENV['SOHO_HOUSE_COIN_CONTRACT_ADDRESS'], abi: abi

2.7.2 :043 > contract.key = Eth::Key.new(priv: '...')
 => #<Eth::Key:0x00007fea3c4e08f8 @private_key=#<MoneyTree::PrivateKey:0x00007fea3c4e0880 @options={:key=>"..."}, @ec_key=#<OpenSSL::PKey::EC:0x00007fea3c4e0858>, @raw_key="... 
2.7.2 :044 > transaction = contract.transact_and_wait.increase_allowance(account2, 1)
 => #<Ethereum::Transaction:0x00007fea2b7be018 @mined=true, @connection=#<Ethereum::HttpClient:0x00007fea3ea94298 @id=0, @log=true, @batch=nil, @formatter=#<Ethereum::Formatter:0x00007fea3ea94248>, @gas_price=22000000000, @gas_limit=4000000, @logger=#<Logger:0x00007fea3ea94108... 
2.7.2 :045 > transaction = contract.transact_and_wait.transfer_from(account2, account1, 1)
 => #<Ethereum::Transaction:0x00007fea2b0f4fc0 @mined=true, @connection=#<Ethereum::HttpClient:0x00007fea3ea94298 @id=0, @log=true, @batch=nil, @formatter=#<Ethereum::Formatter:0x00007fea3ea94248>, @gas_price=22000000000, @gas_limit=4000000, @logger=#<Logger:0x00007fea3ea94108... 
2.7.2 :046 > contract.call.balance_of(account2)
 => 109 
2.7.2 :047 > contract.call.balance_of(account1)
 => 99998891 
tansaku commented 3 years ago

and also works find with:

contract.sender = account2

no need for private key malarcky