small fixes

This commit is contained in:
Jackie 2022-07-21 02:00:57 +02:00 committed by markspanbroek
parent 39005a09be
commit b72fbb0ed9
4 changed files with 30 additions and 50 deletions

View File

@ -151,7 +151,7 @@ method getChainId*(provider: JsonRpcProvider): Future[UInt256] {.async.} =
except CatchableError:
return parse(await client.net_version(), UInt256)
method sendRawTransaction*(provider: JsonRpcProvider, rawTransaction: string): Future[TransactionResponse] {.async.} =
method sendRawTransaction*(provider: JsonRpcProvider, rawTransaction: seq[byte]): Future[TransactionResponse] {.async.} =
convertError:
let
client = await provider.client

View File

@ -8,7 +8,7 @@ proc eth_getTransactionCount(address: Address, blockTag: BlockTag): UInt256
proc eth_estimateGas(transaction: Transaction): UInt256
proc eth_chainId(): UInt256
proc eth_sendTransaction(transaction: Transaction): TransactionHash
proc eth_sendRawTransaction(data: string): TransactionHash
proc eth_sendRawTransaction(data: seq[byte]): TransactionHash
proc eth_getTransactionReceipt(hash: TransactionHash): ?TransactionReceipt
proc eth_sign(account: Address, message: seq[byte]): seq[byte]
proc eth_subscribe(name: string, filter: Filter): JsonNode

View File

@ -9,7 +9,12 @@ import ./signer
export keys
let rng = newRng()
var rng {.threadvar.}: ref HmacDrbgContext
proc getRng: ref HmacDrbgContext =
if rng.isnil:
rng = newRng()
return rng
type SignableTransaction = common.Transaction
@ -35,12 +40,12 @@ proc connect*(wallet: Wallet, provider: JsonRpcProvider) =
wallet.provider = some provider
proc createRandom*(_: type Wallet): Wallet =
result = Wallet()
result.privateKey = PrivateKey.random(rng[])
result.privateKey = PrivateKey.random(getRng()[])
result.publicKey = result.privateKey.toPublicKey()
result.address = Address.init(result.publicKey.toCanonicalAddress())
proc createRandom*(_: type Wallet, provider: JsonRpcProvider): Wallet =
result = Wallet()
result.privateKey = PrivateKey.random(rng[])
result.privateKey = PrivateKey.random(getRng()[])
result.publicKey = result.privateKey.toPublicKey()
result.address = Address.init(result.publicKey.toCanonicalAddress())
result.provider = some provider
@ -51,19 +56,8 @@ method provider*(wallet: Wallet): Provider =
else:
raise newException(WalletError, "Wallet has no provider")
#TODO add other methods defined in signer. Currently you have to specify nonce, gaslimit, gasPrice.
method populateTransaction*(wallet: Wallet, tx: transaction.Transaction): Future[transaction.Transaction] {.async.} =
var populated = tx
if tx.nonce.isNone:
populated.nonce = some(await wallet.getTransactionCount(BlockTag.pending))
if tx.chainId.isNone:
populated.chainId = some(await wallet.getChainId())
if tx.gasLimit.isNone:
populated.gasLimit = some(await wallet.estimateGas(populated))
if tx.gasPrice.isNone and (tx.maxFee.isNone and tx.maxPriorityFee.isNone):
populated.gasPrice = some(await wallet.getGasPrice())
return populated
method getAddress(wallet: Wallet): Future[Address] {.async.} =
return wallet.address
func isPopulated(tx: transaction.Transaction) =
if tx.nonce.isNone or
@ -91,50 +85,31 @@ proc signTransaction(tr: var SignableTransaction, pk: PrivateKey) =
else:
raise newException(WalletError, "Transaction type not supported")
proc signTransaction*(wallet: Wallet, tx: transaction.Transaction): Future[seq[byte]] {.async.} =
if tx.sender.isSome:
doAssert tx.sender.get == wallet.address, "from Address mismatch"
isPopulated(tx)
var s: SignableTransaction
if tx.maxFee.isSome and tx.maxPriorityFee.isSome:
s.txType = TxEip1559
s.maxFee = GasInt(tx.maxFee.get.truncate(uint64))
s.maxPriorityFee = GasInt(tx.maxPriorityFee.get.truncate(uint64))
else:
s.txType = TxLegacy
s.gasPrice = GasInt(tx.gasPrice.get.truncate(uint64))
s.chainId = ChainId(tx.chainId.get.truncate(uint64))
s.gasLimit = GasInt(tx.gasLimit.get.truncate(uint64))
s.nonce = tx.nonce.get.truncate(uint64)
s.to = some EthAddress(tx.to)
s.payload = tx.data
signTransaction(s, wallet.privateKey)
return rlp.encode(s)
method sendTransaction*(wallet: Wallet, tx: transaction.Transaction): Future[TransactionResponse] {.async.} =
if tx.sender.isSome:
doAssert tx.sender.get == wallet.address, "from Address mismatch"
isPopulated(tx)
var s: SignableTransaction
if tx.maxFee.isSome and tx.maxPriorityFee.isSome:
s.txType = TxEip1559
s.maxFee = GasInt(tx.maxFee.get.truncate(uint64))
s.maxPriorityFee = GasInt(tx.maxPriorityFee.get.truncate(uint64))
else:
s.txType = TxLegacy
s.gasPrice = GasInt(tx.gasPrice.get.truncate(uint64))
s.chainId = ChainId(tx.chainId.get.truncate(uint64))
s.gasLimit = GasInt(tx.gasLimit.get.truncate(uint64))
s.nonce = tx.nonce.get.truncate(uint64)
s.to = some EthAddress(tx.to)
s.payload = tx.data
signTransaction(s, wallet.privateKey)
let rawTX = "0x" & rlp.encode(s).toHex
let rawTX = await signTransaction(wallet, tx)
return await wallet.provider.get.sendRawTransaction(rawTX)
proc signTransaction*(wallet: Wallet, tx: transaction.Transaction): Future[string] {.async.} =
if tx.sender.isSome:
doAssert tx.sender.get == wallet.address, "from Address mismatch"
isPopulated(tx)
var s: SignableTransaction
if tx.maxFee.isSome and tx.maxPriorityFee.isSome:
s.txType = TxEip1559
s.maxFee = GasInt(tx.maxFee.get.truncate(uint64))
s.maxPriorityFee = GasInt(tx.maxPriorityFee.get.truncate(uint64))
else:
s.txType = TxLegacy
s.gasPrice = GasInt(tx.gasPrice.get.truncate(uint64))
s.chainId = ChainId(tx.chainId.get.truncate(uint64))
s.gasLimit = GasInt(tx.gasLimit.get.truncate(uint64))
s.nonce = tx.nonce.get.truncate(uint64)
s.to = some EthAddress(tx.to)
s.payload = tx.data
signTransaction(s, wallet.privateKey)
return "0x" & rlp.encode(s).toHex
#TODO add functionality to sign messages
#TODO add functionality to create wallets from Mnemoniks or Keystores

View File

@ -13,6 +13,16 @@ suite "Wallet":
#TODO take close look at current signing tests. I am not 100% sure they are correct and work
#TODO add setup/teardown if required. Currently doing all nonces manually
var provider: JsonRpcProvider
var snapshot: JsonNode
setup:
provider = JsonRpcProvider.new()
snapshot = await provider.send("evm_snapshot")
#teardown:
# discard await provider.send("evm_revert", @[snapshot])
test "Can create Wallet with private key":
discard Wallet.new(pk1)
@ -24,7 +34,6 @@ suite "Wallet":
discard Wallet.new(pk1, provider)
test "Can connect Wallet to provider":
let provider = JsonRpcProvider.new()
let wallet = Wallet.new(pk1)
wallet.connect(provider)
@ -32,7 +41,6 @@ suite "Wallet":
discard Wallet.createRandom()
test "Can create Random Wallet with provider":
let provider = JsonRpcProvider.new()
discard Wallet.createRandom(provider)
test "Multiple Random Wallets are different":
@ -55,7 +63,7 @@ suite "Wallet":
gasLimit: some 21_000.u256,
)
let signedTx = await wallet.signTransaction(tx)
check signedTx == "0xf86380843b9aca0082520894328809bc894f92807417d2dad6b7c998c1afdac680801ba04ae9b24cba72103bb30a1e91c016796fc2bf2d46d2b75ca80211fae0337c3c03a05e3c81ce9944a07f18b65142a1847c5b72f993c8e7c28d5d4360ff36a2fed049"
check signedTx == @[248.byte, 99, 128, 132, 59, 154, 202, 0, 130, 82, 8, 148, 50, 136, 9, 188, 137, 79, 146, 128, 116, 23, 210, 218, 214, 183, 201, 152, 193, 175, 218, 198, 128, 128, 27, 160, 74, 233, 178, 76, 186, 114, 16, 59, 179, 10, 30, 145, 192, 22, 121, 111, 194, 191, 45, 70, 210, 183, 92, 168, 2, 17, 250, 224, 51, 124, 60, 3, 160, 94, 60, 129, 206, 153, 68, 160, 127, 24, 182, 81, 66, 161, 132, 124, 91, 114, 249, 147, 200, 231, 194, 141, 93, 67, 96, 255, 54, 162, 254, 208, 73]
test "Can sign manually created contract call":
let wallet = Wallet.new(pk1)
@ -68,7 +76,7 @@ suite "Wallet":
gasLimit: some 21_000.u256,
)
let signedTx = await wallet.signTransaction(tx)
check signedTx == "0xf86780843b9aca0082520894328809bc894f92807417d2dad6b7c998c1afdac6808418160ddd1ca029261fc74ffbbb5ce3d0a3b6eac9726f05d8a849e0f1535722e057bdd83b9659a044f857852bd8b7bb8c0c0a5a61c2c56fce42edacab73f42301b509edb7600ff1"
check signedTx == @[248.byte, 103, 128, 132, 59, 154, 202, 0, 130, 82, 8, 148, 50, 136, 9, 188, 137, 79, 146, 128, 116, 23, 210, 218, 214, 183, 201, 152, 193, 175, 218, 198, 128, 132, 24, 22, 13, 221, 28, 160, 41, 38, 31, 199, 79, 251, 187, 92, 227, 208, 163, 182, 234, 201, 114, 111, 5, 216, 168, 73, 224, 241, 83, 87, 34, 224, 87, 189, 216, 59, 150, 89, 160, 68, 248, 87, 133, 43, 216, 183, 187, 140, 12, 10, 90, 97, 194, 197, 111, 206, 66, 237, 172, 171, 115, 244, 35, 1, 181, 9, 237, 183, 96, 15, 241]
test "Can sign manually created tx with EIP1559":
let wallet = Wallet.new(pk1)
@ -81,10 +89,9 @@ suite "Wallet":
gasLimit: some 21_000.u256
)
let signedTx = await wallet.signTransaction(tx)
check signedTx == "0x02f86c827a6980843b9aca00847735940082520894328809bc894f92807417d2dad6b7c998c1afdac68080c001a0162929fc5b4cb286ed4cd630d172d1dd747dad4ffbeb413b037f21168f4fe366a062b931c1fc55028ae1fdf5342564300cae251791d785a0efd31c088405a651e7"
check signedTx == @[2.byte, 248, 108, 130, 122, 105, 128, 132, 59, 154, 202, 0, 132, 119, 53, 148, 0, 130, 82, 8, 148, 50, 136, 9, 188, 137, 79, 146, 128, 116, 23, 210, 218, 214, 183, 201, 152, 193, 175, 218, 198, 128, 128, 192, 1, 160, 22, 41, 41, 252, 91, 76, 178, 134, 237, 76, 214, 48, 209, 114, 209, 221, 116, 125, 173, 79, 251, 235, 65, 59, 3, 127, 33, 22, 143, 79, 227, 102, 160, 98, 185, 49, 193, 252, 85, 2, 138, 225, 253, 245, 52, 37, 100, 48, 12, 174, 37, 23, 145, 215, 133, 160, 239, 211, 28, 8, 132, 5, 166, 81, 231]
test "Can send rawTransaction":
let provider = JsonRpcProvider.new()
let wallet = Wallet.new(pk_with_funds)
let tx = Transaction(
to: wallet.address,
@ -99,7 +106,6 @@ suite "Wallet":
test "Can call state-changing function automatically":
#TODO add actual token contract, not random address. Should work regardless
let provider = JsonRpcProvider.new()
let wallet = Wallet.new(pk_with_funds, provider)
let overrides = TransactionOverrides(
nonce: some 1.u256,
@ -110,7 +116,6 @@ suite "Wallet":
test "Can call state-changing function automatically EIP1559":
#TODO add actual token contract, not random address. Should work regardless
let provider = JsonRpcProvider.new()
let wallet = Wallet.new(pk_with_funds, provider)
let overrides = TransactionOverrides(
nonce: some 2.u256,