21f98c4086 | ||
---|---|---|
.github/workflows | ||
ethers | ||
testmodule | ||
testnode | ||
.editorconfig | ||
.gitignore | ||
License.md | ||
Readme.md | ||
ethers.nim | ||
ethers.nimble | ||
nim.cfg |
Readme.md
Nim Ethers
A port of the ethers.js library to Nim. Allows you to connect to an Ethereum node.
This is very much a work in progress; expect to see many things that are incomplete or wrong. Use at your own risk.
Installation
Use the Nimble package manager to add ethers
to an existing
project. Add the following to its .nimble file:
requires "https://github.com/status-im/nim-ethers >= 0.1.0 & < 0.2.0"
Usage
To connect to an Ethereum node, you require a Provider
. Currently, only a
JSON-RPC provider is supported:
import ethers
import chronos
let provider = JsonRpcProvider.new("ws://localhost:8545")
let accounts = await provider.listAccounts()
To interact with a smart contract, you need to define the contract functions in Nim. For example, to interact with an ERC20 token, you could define the following:
type Erc20 = ref object of Contract
proc totalSupply(token: Erc20): UInt256 {.contract, view.}
proc balanceOf(token: Erc20, account: Address): UInt256 {.contract, view.}
proc transfer(token: Erc20, recipient: Address, amount: UInt256) {.contract.}
proc allowance(token: Erc20, owner, spender: Address): UInt256 {.contract, view.}
proc approve(token: Erc20, spender: Address, amount: UInt256) {.contract.}
proc transferFrom(token: Erc20, sender, recipient: Address, amount: UInt256) {.contract.}
Notice how some functions are annotated with a {.view.}
pragma. This indicates
that the function does not modify the blockchain. See also the Solidity
documentation on state mutability
Now that you've defined the contract interface, you can create an instance of it using its deployed address:
let address = Address.init("0x.....")
let token = Erc20.new(address, provider)
The functions that you defined earlier can now be called asynchronously:
let supply = await token.totalSupply()
let balance = await token.balanceOf(accounts[0])
These invocations do not yet change the state of the blockchain, even when we
invoke those functions that lack a {.view.}
pragma. To allow these changes to
happen, we require an instance of a Signer
first.
For example, to use the 4th account on the Ethereum node to sign transactions, you'd instantiate the signer as follows:
let signer = provider.getSigner(accounts[3])
And then connect the contract and signer:
let writableToken = token.connect(signer)
This allows you to make changes to the state of the blockchain:
await writableToken.transfer(accounts[7], 42.u256)
Which transfers 42 tokens from account 3 to account 7
Thanks
This library is inspired by the great work done by the ethers.js (no affiliation) and nim-web3 developers.