Started work on event loop and callback structure
This commit is contained in:
parent
0c82c97369
commit
c3d4029a9c
|
@ -15,7 +15,7 @@ proc eth_mining(): bool
|
|||
proc eth_hashrate(): int
|
||||
proc eth_gasPrice(): int64
|
||||
proc eth_accounts(): seq[array[20, byte]]
|
||||
proc eth_blockNumber(): int
|
||||
proc eth_blockNumber(): string
|
||||
proc eth_getBalance(data: array[20, byte], quantityTag: string): int
|
||||
proc eth_getStorageAt(data: array[20, byte], quantity: int, quantityTag: string): seq[byte]
|
||||
proc eth_getTransactionCount(data: array[20, byte], quantityTag: string)
|
||||
|
|
|
@ -102,10 +102,10 @@ type
|
|||
# TODO: I don't think this will work as input, need only one value that is either UInt256 or seq[UInt256]
|
||||
|
||||
FilterOptions* = object
|
||||
fromBlock*: string # (optional, default: "latest") integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
|
||||
toBlock*: string # (optional, default: "latest") integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
|
||||
address*: seq[array[20, byte]] # (optional) contract address or a list of addresses from which logs should originate.
|
||||
topics*: seq[FilterData] # (optional) list of DATA topics. Topics are order-dependent. Each topic can also be a list of DATA with "or" options.
|
||||
fromBlock*: Option[string] # (optional, default: "latest") integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
|
||||
toBlock*: Option[string] # (optional, default: "latest") integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
|
||||
address*: Option[string] # (optional) contract address or a list of addresses from which logs should originate.
|
||||
topics*: Option[seq[string]]#Option[seq[FilterData]] # (optional) list of DATA topics. Topics are order-dependent. Each topic can also be a list of DATA with "or" options.
|
||||
|
||||
LogObject* = object
|
||||
#removed*: bool # true when the log was removed, due to a chain reorganization. false if its a valid log.
|
||||
|
@ -189,3 +189,17 @@ proc `%`*(x: EthCall): JsonNode =
|
|||
result["value"] = %x.value.unsafeGet
|
||||
if x.data.isSome:
|
||||
result["data"] = %x.data.unsafeGet
|
||||
|
||||
proc `%`*(x: byte): JsonNode =
|
||||
%x.int
|
||||
|
||||
proc `%`*(x: FilterOptions): JsonNode =
|
||||
result = newJobject()
|
||||
if x.fromBlock.isSome:
|
||||
result["fromBlock"] = %x.fromBlock.unsafeGet
|
||||
if x.toBlock.isSome:
|
||||
result["toBlock"] = %x.toBlock.unsafeGet
|
||||
if x.address.isSome:
|
||||
result["address"] = %x.address.unsafeGet
|
||||
if x.topics.isSome:
|
||||
result["topics"] = %x.topics.unsafeGet
|
||||
|
|
41
src/web3.nim
41
src/web3.nim
|
@ -1,5 +1,5 @@
|
|||
import macros, strutils, options, math, json
|
||||
from os import getCurrentDir, DirSep
|
||||
from os import getCurrentDir, DirSep, sleep
|
||||
import
|
||||
nimcrypto, stint, httputils, chronicles, asyncdispatch2, json_rpc/rpcclient
|
||||
import ethtypes, ethprocs, stintjson, ethhexstrings
|
||||
|
@ -286,9 +286,16 @@ proc parseContract(body: NimNode): seq[InterfaceObject] =
|
|||
macro contract(cname: untyped, body: untyped): untyped =
|
||||
var objects = parseContract(body)
|
||||
result = newStmtList()
|
||||
let address = ident "address"
|
||||
result.add quote do:
|
||||
type
|
||||
`cname` = distinct Contract
|
||||
#`cname` = distinct Contract
|
||||
`cname` = ref object
|
||||
`address`: array[20, byte]
|
||||
#callbacks: tuple[
|
||||
# Transfer: seq[proc (fromAddr: Address, toAddr: Address, value: Uint256)]
|
||||
#]
|
||||
|
||||
for obj in objects:
|
||||
if obj.kind == function:
|
||||
echo obj.functionObject.outputs
|
||||
|
@ -328,7 +335,8 @@ macro contract(cname: untyped, body: untyped): untyped =
|
|||
procDef[6].add quote do:
|
||||
var cc: EthCall
|
||||
cc.source = some(`senderName`.address)
|
||||
cc.to = `senderName`.contract.Contract.address
|
||||
#cc.to = `senderName`.contract.Contract.address
|
||||
cc.to = `senderName`.contract.address
|
||||
cc.data = some("0x" & ($keccak_256.digest(`signature`))[0..<8].toLower & `encodedParams`)
|
||||
let response = waitFor `client`.eth_call(cc, "latest")
|
||||
return response
|
||||
|
@ -336,7 +344,8 @@ macro contract(cname: untyped, body: untyped): untyped =
|
|||
procDef[6].add quote do:
|
||||
var cc: EthSend
|
||||
cc.source = `senderName`.address
|
||||
cc.to = some(`senderName`.contract.Contract.address)
|
||||
#cc.to = some(`senderName`.contract.Contract.address)
|
||||
cc.to = some(`senderName`.contract.address)
|
||||
cc.data = "0x" & ($keccak_256.digest(`signature`))[0..<8].toLower & `encodedParams`
|
||||
let response = waitFor `client`.eth_sendTransaction(cc)
|
||||
return response
|
||||
|
@ -393,7 +402,26 @@ macro toAddress(input: string): untyped =
|
|||
ident "byte"
|
||||
)
|
||||
|
||||
var x = Contract(address: "254dffcd3277C0b1660F6d42EFbB754edaBAbC2B".toAddress).TestContract
|
||||
proc eventListen(callback: proc(receipt: LogObject)) =
|
||||
var client = newRpcHttpClient()
|
||||
client.httpMethod(MethodPost)
|
||||
waitFor client.connect("127.0.0.1", Port(8545))
|
||||
var lastBlock = "0x" & (parseHexInt((waitFor client.eth_blockNumber())[2..^1]) + 1).toHex[^2..^1]
|
||||
while true:
|
||||
waitFor client.connect("127.0.0.1", Port(8545))
|
||||
let response = waitFor client.eth_getLogs(FilterOptions(fromBlock: some(lastBlock), toBlock: none(string), address: some("0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B".toLower), topics: none(seq[string])))
|
||||
if response.len > 0:
|
||||
lastBlock = "0x" & (parseHexInt(response[^1].blockNumber[2..^1]) + 1).toHex[^2..^1]
|
||||
for receipt in response:
|
||||
callback(receipt)
|
||||
sleep(1000)
|
||||
|
||||
var thr: Thread[proc(receipt: LogObject)]
|
||||
createThread(thr, eventListen, proc(receipt: LogObject) =
|
||||
echo receipt
|
||||
)
|
||||
|
||||
var x = TestContract(address: "254dffcd3277C0b1660F6d42EFbB754edaBAbC2B".toAddress)#.TestContract
|
||||
|
||||
echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).getBalance(
|
||||
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0")
|
||||
|
@ -401,10 +429,11 @@ echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAd
|
|||
|
||||
echo toHex(x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).sendCoin(
|
||||
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0"),
|
||||
100000.to(Stuint[256])
|
||||
256.to(Stuint[256])
|
||||
))
|
||||
|
||||
echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).getBalance(
|
||||
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0")
|
||||
)
|
||||
#echo "0x" & $keccak_256.digest("Transfer(address,address,uint256)")
|
||||
joinThreads([thr])
|
||||
|
|
Loading…
Reference in New Issue