Skip to content

Commit b3474dc

Browse files
committed
#9: try
1 parent 9b8608e commit b3474dc

File tree

9 files changed

+64
-24
lines changed

9 files changed

+64
-24
lines changed

Gemfile

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ source 'https://rubygems.org'
2424
gemspec
2525

2626
gem 'donce', '>0', require: false
27-
gem 'eth', '>0', require: false
2827
gem 'loog', '>0', require: false
2928
gem 'minitest', '5.25.4', require: false
3029
gem 'minitest-reporters', '1.7.1', require: false

Gemfile.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ PATH
33
specs:
44
erc20 (0.0.0)
55
backtrace (> 0)
6+
eth (~> 0.4)
67
jsonrpc-client (> 0)
78
tago (> 0)
89

@@ -262,7 +263,6 @@ PLATFORMS
262263
DEPENDENCIES
263264
donce (> 0)
264265
erc20!
265-
eth (> 0)
266266
loog (> 0)
267267
minitest (= 5.25.4)
268268
minitest-reporters (= 1.7.1)

erc20.gemspec

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
4040
s.rdoc_options = ['--charset=UTF-8']
4141
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
4242
s.add_dependency 'backtrace', '>0'
43+
s.add_dependency 'eth', '~>0.4'
4344
s.add_dependency 'jsonrpc-client', '>0'
4445
s.add_dependency 'tago', '>0'
4546
s.metadata['rubygems_mfa_required'] = 'true'

hardhat/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ artifacts/
22
cache/
33
node_modules/
44
ignition/deployments/
5+
package-lock.json

hardhat/contracts/Foo.sol

+2-7
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ contract Foo {
2626
constructor() {
2727
owner = msg.sender;
2828
_mint(owner, 100000);
29-
_mint(0xd5fF1bFCDE7A03Da61ad229d962c74F1eA2f16A5, 123000); // Jeff
30-
_mint(0xd7a63Ac9DD3d7878bc042A4bADA214EE4aff8c85, 456000); // Walter
29+
_mint(0xd5fF1bFCDE7A03Da61ad229d962c74F1eA2f16A5, 123000000000); // Jeff
30+
_mint(0xd7a63Ac9DD3d7878bc042A4bADA214EE4aff8c85, 456000000000); // Walter
3131
}
3232

3333
function balanceOf(address account) external view returns (uint256) {
@@ -55,7 +55,6 @@ contract Foo {
5555
) external returns (bool) {
5656
uint256 currentAllowance = _allowances[sender][msg.sender];
5757
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
58-
5958
_approve(sender, msg.sender, currentAllowance - amount);
6059
_transfer(sender, recipient, amount);
6160

@@ -71,10 +70,8 @@ contract Foo {
7170
require(sender != address(0), "ERC20: transfer from the zero address");
7271
require(recipient != address(0), "ERC20: transfer to the zero address");
7372
require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
74-
7573
_balances[sender] -= amount;
7674
_balances[recipient] += amount;
77-
7875
emit Transfer(sender, recipient, amount);
7976
}
8077

@@ -85,14 +82,12 @@ contract Foo {
8582
) internal {
8683
require(tokenOwner != address(0), "ERC20: approve from the zero address");
8784
require(spender != address(0), "ERC20: approve to the zero address");
88-
8985
_allowances[tokenOwner][spender] = amount;
9086
emit Approval(tokenOwner, spender, amount);
9187
}
9288

9389
function _mint(address account, uint256 amount) internal {
9490
require(account != address(0), "ERC20: mint to the zero address");
95-
9691
totalSupply += amount;
9792
_balances[account] += amount;
9893
emit Transfer(address(0), account, amount);

hardhat/hardhat.config.js

+12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,19 @@ module.exports = {
2626
solidity: "0.8.28",
2727
defaultNetwork: "foo",
2828
networks: {
29+
hardhat: {
30+
chainId: 4242,
31+
gas: 10,
32+
gasPrice: 4,
33+
maxFeePerGas: 100,
34+
maxPriorityFeePerGas: 100,
35+
initialBaseFeePerGas: 100,
36+
accounts: {
37+
count: 1
38+
}
39+
},
2940
foo: {
41+
chainId: 4242,
3042
url: "http://HOST:PORT"
3143
}
3244
}

lib/erc20/wallet.rb

+27-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
# SOFTWARE.
2222

23+
require 'eth'
2324
require 'jsonrpc/client'
2425
require_relative '../erc20'
2526

@@ -58,13 +59,33 @@ def balance(hex)
5859

5960
# Send a single payment from a private address to a public one.
6061
#
61-
# @param [String] _sender Private key, in hex
62-
# @param [String] _receiver Public key, in hex
63-
# @param [Integer] _amount The amount to send
62+
# @param [String] priv Private key, in hex
63+
# @param [String] address Public key, in hex
64+
# @param [Integer] amount The amount of ERC20 tokens to send
6465
# @return [String] Transaction hash
65-
def pay(_sender, _receiver, _amount)
66-
# do it
67-
'abcdef'
66+
def pay(priv, address, amount)
67+
func = 'a9059cbb' # transfer(address,uint256)
68+
to_clean = address.downcase.sub(/^0x/, '')
69+
to_padded = '0' * (64 - to_clean.size) + to_clean
70+
amt_hex = amount.to_s(16)
71+
amt_padded = '0' * (64 - amt_hex.size) + amt_hex
72+
data = "0x#{func}#{to_padded}#{amt_padded}"
73+
key = Eth::Key.new(priv: priv)
74+
from = key.address
75+
nonce = client.eth_getTransactionCount(from, 'pending').to_i(16)
76+
gas = client.eth_estimateGas({ from:, to: @contract, data: data}, 'latest').to_i(16)
77+
@log.info("Gas: #{gas}")
78+
tx = Eth::Tx.new({
79+
nonce:,
80+
gas_price: 1000,
81+
gas_limit: gas * 100,
82+
to: @contract,
83+
value: 0,
84+
data: data,
85+
chain_id: 4242
86+
})
87+
tx.sign(key)
88+
client.eth_sendRawTransaction("0x" + tx.hex)
6889
end
6990

7091
# Wait for incoming transactions and let the block know when they

test/erc20/test_wallet.rb

+18-7
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,19 @@ def test_checks_balance_on_testnet
7676
def test_checks_balance_on_hardhat
7777
on_hardhat do |wallet|
7878
b = wallet.balance(Eth::Key.new(priv: JEFF).address.to_s)
79-
assert_equal(123_000, b)
79+
assert_equal(123_000_000_000, b)
80+
end
81+
end
82+
83+
def test_pays_on_hardhat
84+
on_hardhat do |wallet|
85+
to = Eth::Key.new(priv: WALTER).address.to_s
86+
before = wallet.balance(to)
87+
sum = 42_000
88+
from = Eth::Key.new(priv: JEFF).address.to_s
89+
assert(wallet.balance(from) > sum * 2)
90+
wallet.pay(JEFF, to, sum)
91+
assert_equal(before - sum, wallet.balance(to))
8092
end
8193
end
8294

@@ -147,27 +159,26 @@ def on_hardhat
147159
home: File.join(__dir__, '../../hardhat'),
148160
ports: { port => 8545 },
149161
command: 'npx hardhat node',
150-
log: Loog::NULL
162+
log: Loog::VERBOSE
151163
) do
152164
wait_for(port)
153165
cmd = [
154166
'(cat hardhat.config.js)',
155167
'(ls -al)',
156-
'(npx hardhat ignition deploy ./ignition/modules/Foo.ts --network foo)',
157-
'(npx hardhat ignition deployments | tail -1 > /tmp/deployment.txt)',
158-
'(npx hardhat ignition status "$(cat /tmp/deployment.txt)" | tail -1 | cut -d" " -f3)'
168+
'(echo y | npx hardhat ignition deploy ./ignition/modules/Foo.ts --network foo --deployment-id foo)',
169+
'(npx hardhat ignition status foo | tail -1 | cut -d" " -f3)'
159170
].join(' && ')
160171
contract = donce(
161172
home: File.join(__dir__, '../../hardhat'),
162173
command: "/bin/bash -c #{Shellwords.escape(cmd)}",
163174
build_args: { 'HOST' => donce_host, 'PORT' => port },
164-
log: Loog::NULL,
175+
log: Loog::VERBOSE,
165176
root: true
166177
).split("\n").last
167178
wallet = ERC20::Wallet.new(
168179
contract:,
169180
rpc: "http://localhost:#{port}",
170-
log: Loog::NULL
181+
log: Loog::VERBOSE
171182
)
172183
yield wallet
173184
end

test/test__helper.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
3636

3737
# To make tests retry on failure:
38-
require 'minitest/retry'
39-
Minitest::Retry.use!(methods_to_skip: [])
38+
# require 'minitest/retry'
39+
# Minitest::Retry.use!(methods_to_skip: [])

0 commit comments

Comments
 (0)