nim-web3/tests/test.nim

194 lines
7.3 KiB
Nim

import pkg/unittest2
import ../web3
import chronos, nimcrypto, options, json, stint, parseutils
import test_utils
contract(EncodingTest):
proc setBool(val: Bool)
proc getBool(): Bool {.view.}
const EncodingTestCode = "608060405260008060006101000a81548160ff02191690831515021790555034801561002a57600080fd5b506101048061003a6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806312a7b91414604e5780631e26fd3314607a575b600080fd5b348015605957600080fd5b50606060a6565b604051808215151515815260200191505060405180910390f35b348015608557600080fd5b5060a460048036038101908080351515906020019092919050505060bc565b005b60008060009054906101000a900460ff16905090565b806000806101000a81548160ff021916908315150217905550505600a165627a7a72305820be0033d3993a43508dbcb21e47d345021ad5f89e26e035767fdae7ba9ef2ae310029"
#[ Contract EncodingTest
pragma solidity ^0.4.18;
contract EncodingTest {
bool boolVal = false;
function setBool(bool _boolVal) public {
boolVal = _boolVal;
}
function getBool() public constant returns (bool) {
return boolVal;
}
}
]#
#[ Contract NumberStorage
pragma solidity ^0.4.18;
contract NumberStorage {
uint num;
function setNumber(uint _num) public {
num = _num;
}
function getNumber() public constant returns (uint) {
return num;
}
}
]#
contract(NumberStorage):
proc setNumber(number: Uint256)
proc getNumber(): Uint256 {.view.}
const NumberStorageCode = "6060604052341561000f57600080fd5b60bb8061001d6000396000f30060606040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fb5c1cb8114604d578063f2c9ecd8146062575b600080fd5b3415605757600080fd5b60606004356084565b005b3415606c57600080fd5b60726089565b60405190815260200160405180910390f35b600055565b600054905600a165627a7a7230582023e722f35009f12d5698a4ab22fb9d55a6c0f479fc43875c65be46fbdd8db4310029"
#[ Contract MetaCoin
pragma solidity >=0.4.25 <0.6.0;
contract MetaCoin {
mapping (address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
constructor() public {
balances[tx.origin] = 10000;
}
function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Transfer(msg.sender, receiver, amount);
return true;
}
function getBalance(address addr) public view returns(uint) {
return balances[addr];
}
}
]#
contract(MetaCoin):
proc sendCoin(receiver: Address, amount: Uint256): Bool
proc getBalance(address: Address): Uint256 {.view.}
proc Transfer(fromAddr, toAddr: indexed[Address], value: Uint256) {.event.}
proc BlaBla(fromAddr: indexed[Address]) {.event.}
const MetaCoinCode = "608060405234801561001057600080fd5b5032600090815260208190526040902061271090556101c2806100346000396000f30060806040526004361061004b5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166390b98a118114610050578063f8b2cb4f14610095575b600080fd5b34801561005c57600080fd5b5061008173ffffffffffffffffffffffffffffffffffffffff600435166024356100d5565b604080519115158252519081900360200190f35b3480156100a157600080fd5b506100c373ffffffffffffffffffffffffffffffffffffffff6004351661016e565b60408051918252519081900360200190f35b336000908152602081905260408120548211156100f457506000610168565b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260208190526040902054905600a165627a7a72305820000313ec0ebbff4ffefbe79d615d0ab019d8566100c40eb95a4eee617a87d1090029"
suite "Contracts":
var web3: Web3
var accounts: seq[Address]
setup:
proc asyncsetup {.async.} =
web3 = await newWeb3("ws://127.0.0.1:8545/")
accounts = await web3.provider.eth_accounts()
echo "accounts: ", accounts
web3.defaultAccount = accounts[0]
waitFor asyncsetup()
teardown:
proc asyncteardown {.async.} =
await web3.close()
waitFor asyncteardown()
test "encoding test":
proc asynctest {.async.} =
let
receipt = await web3.deployContract(EncodingTestCode)
cc = receipt.contractAddress.get
echo "Deployed EncodingTest contract: ", cc
let ns = web3.contractSender(EncodingTest, cc)
var b = await ns.getBool().call()
assert(b == Bool.parse(false))
echo "setBool: ", await ns.setBool(Bool.parse(true)).send()
b = await ns.getBool().call()
assert(b == Bool.parse(true))
waitFor asynctest()
test "number storage":
proc asynctest {.async.} =
let
receipt = await web3.deployContract(NumberStorageCode)
cc = receipt.contractAddress.get
echo "Deployed NumberStorage contract: ", cc
let ns = web3.contractSender(NumberStorage, cc)
echo "setnumber: ", await ns.setNumber(5.u256).send()
let n = await ns.getNumber().call()
assert(n == 5.u256)
waitFor asynctest()
test "metacoin":
proc asynctest {.async.} =
let
receipt = await web3.deployContract(MetaCoinCode)
cc = receipt.contractAddress.get
var deployedAtBlock: uint64
discard parseHex(receipt.blockNumber, deployedAtBlock)
echo "Deployed MetaCoin contract: ", cc, " at block ", deployedAtBlock
let ns = web3.contractSender(MetaCoin, cc)
let notifFut = newFuture[void]()
var notificationsReceived = 0
let s = await ns.subscribe(Transfer) do (
fromAddr, toAddr: Address, value: Uint256)
{.raises: [Defect], gcsafe.}:
try:
echo "onTransfer: ", fromAddr, " transferred ", value, " to ", toAddr
inc notificationsReceived
assert(fromAddr == web3.defaultAccount)
assert((notificationsReceived == 1 and value == 50.u256) or
(notificationsReceived == 2 and value == 100.u256))
if notificationsReceived == 2:
notifFut.complete()
except Exception as err:
# chronos still raises exceptions which inherit directly from Exception
doAssert false, err.msg
echo "getbalance (now): ", await ns.getBalance(web3.defaultAccount).call()
echo "getbalance (after creation): ", await ns.getBalance(web3.defaultAccount).call(blockNumber = deployedAtBlock)
# Let's try to get the balance at a point in time where the contract was not deployed yet:
try:
echo "getbalance (first block): ", await ns.getBalance(web3.defaultAccount).call(blockNumber = 1'u64)
except CatchableError as err:
echo "getbalance (first block): ", err.msg
echo "sendCoin: ", await ns.sendCoin(accounts[1], 50.u256).send()
let newBalance1 = await ns.getBalance(web3.defaultAccount).call()
assert(newBalance1 == 9950.u256)
let newBalance2 = await ns.getBalance(accounts[1]).call()
assert(newBalance2 == 50.u256)
echo "sendCoin: ", await ns.sendCoin(accounts[1], 100.u256).send()
echo "transfers: ", await ns.getJsonLogs(
Transfer,
fromBlock = some(blockId(deployedAtBlock)),
toBlock = some(blockId(1000'u64)))
await notifFut
await s.unsubscribe()
waitFor asynctest()