Taesoo Kim
Taesoo Kim
geth
, web3.js
, MetaMask> a0 = eth.accounts[0]
> a1 = eth.accounts[0]
> tx = eth.sign_transaction({
"from": a0, "to": a1, "value": web3.toWei(1, "gwei"),
// recommended gas price of the network, 1000000007 wei (~= 1 gwei)
"gasPrice": eth.gas_price,
// > base fee of 21,000
"gas": 25000,
// #trasnactions sent so far
"nonce": eth.get_transaction_count(a0)
})
> tx.tx
{ // what we provided
to: "0x5e3fc8f77d1c499c7c178d3efac6f62a1f9c669e",
value: "0x3b9aca00", gas: "0x61a8", gasPrice: "0x3b9aca07", nonce: "0x6",
// empty fields
input: "0x",
maxFeePerGas: null,
maxPriorityFeePerGas: null,
// hash = keccat(tx.raw), (r, s, v) = a transaction's signature
hash: "0x33a4fca9102b531b23b16b53e845f22ba58dcde0bf50c38a3b2999c240bedd6c",
r: "0xcf20b1cfc8eb1d441e64c1db2bde01bdfcdf7500d86fcfef788cfcfe96e15596",
s: "0x5d117bc559fc4a55a19785d4fa1ef97f6e666cfda892b12331b33a9ded4dbb0b",
v: "0xa96",
// indicating that it's a legacy transaction
type: "0x0" }
> rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
[] : f869 // 0xf8-0xf7 = 1-byte, 0x69 = 105 bytes
nonce : 06 // a single byte [0, 0x7f]
gasPrice: 84 3b9aca07 // 4-byte: 0x84 - 0x80
gasLimit: 82 61a8 // 2-byte: 0x82 - 0x80
to : 94 5e3fc8f77d1c499c7c178d3efac6f62a1f9c669e
value : 84 3b9aca00
data : 80 // 0-byte (nil)
v : 82 0a96 // 2710 = 1337 (chain id) * 2 + 36
r : a0 cf20b1cfc8eb1d441e64c1db2bde01bdfcdf7500d86fcfef788cfcfe96e15596
s : a0 5d117bc559fc4a55a19785d4fa1ef97f6e666cfda892b12331b33a9ded4dbb0b"
import rlp
nonce = 6
gasprice = 0x3b9aca07
to = 0x5e3fc8f77d1c499c7c178d3efac6f62a1f9c669e
value = 0x3b9aca00
data = ""
gaslimit = 0x61a8
hash = 0x33a4fca9102b531b23b16b53e845f22ba58dcde0bf50c38a3b2999c240bedd6c
r = 0xcf20b1cfc8eb1d441e64c1db2bde01bdfcdf7500d86fcfef788cfcfe96e15596
s = 0x5d117bc559fc4a55a19785d4fa1ef97f6e666cfda892b12331b33a9ded4dbb0b
chainid = 1337
v = 1337*2 + 36
rlp.encode([nonce, gasprice, gaslimit, to, value, data, v, r, s])
signing_data = rlp.encode(
[nonce, gasprice, gaslimit, to, value, data, chainid, 0, 0])
signing_data_hash = web3.keccak(primitive=signing_data)
sk = PrivateKey(...)
sig = sk.sign_msg_hash(signing_data_hash)
v = sig.v + chainid*2 + 35
r = sig.r
s = sig.s
raw = rlp.encode([nonce, gasprice, gaslimit, to, value, data, v, r, s])
print(HexBytes(raw).hex())
→ You can construct and send a raw transaction!
Ref. EI §1
Ref. EI §1
Ref. EI §1
Ref. EI §1
txs = []
for i in range(10):
txs.append(send_transaction({"from": a0, "to": a1, "value": 1 gwei}))
# is this going to be accepted first? (a0 to a1)
txs.append(send_transaction(
{"from": a0, "to": a1, "value": 1 gwei, "gasPrice": eth.gas_price*100}))
# is this going to be accepted first? (a1 to a0)
txs.append(send_transaction(
{"from": a1, "to": a0, "value": 1 gwei, "gasPrice": eth.gas_price*100}))
# 11? vs 0?
web3.eth.get_transaction_receipt(txs[-1]).transactionIndex
Ref. EI §1
Ref. EI §2
Storage.sol
, Owner.sol
and Ballot.sol
from Remix/Brownie