Started work on event loop and callback structure

This commit is contained in:
PMunch 2019-01-07 17:59:57 +01:00
parent 0c82c97369
commit c3d4029a9c
3 changed files with 54 additions and 11 deletions

View File

@ -15,7 +15,7 @@ proc eth_mining(): bool
proc eth_hashrate(): int proc eth_hashrate(): int
proc eth_gasPrice(): int64 proc eth_gasPrice(): int64
proc eth_accounts(): seq[array[20, byte]] 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_getBalance(data: array[20, byte], quantityTag: string): int
proc eth_getStorageAt(data: array[20, byte], quantity: int, quantityTag: string): seq[byte] proc eth_getStorageAt(data: array[20, byte], quantity: int, quantityTag: string): seq[byte]
proc eth_getTransactionCount(data: array[20, byte], quantityTag: string) proc eth_getTransactionCount(data: array[20, byte], quantityTag: string)

View File

@ -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] # TODO: I don't think this will work as input, need only one value that is either UInt256 or seq[UInt256]
FilterOptions* = object 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. 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*: 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*: seq[array[20, byte]] # (optional) contract address or a list of addresses from which logs should originate. address*: Option[string] # (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. 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 LogObject* = object
#removed*: bool # true when the log was removed, due to a chain reorganization. false if its a valid log. #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 result["value"] = %x.value.unsafeGet
if x.data.isSome: if x.data.isSome:
result["data"] = %x.data.unsafeGet 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

View File

@ -1,5 +1,5 @@
import macros, strutils, options, math, json import macros, strutils, options, math, json
from os import getCurrentDir, DirSep from os import getCurrentDir, DirSep, sleep
import import
nimcrypto, stint, httputils, chronicles, asyncdispatch2, json_rpc/rpcclient nimcrypto, stint, httputils, chronicles, asyncdispatch2, json_rpc/rpcclient
import ethtypes, ethprocs, stintjson, ethhexstrings import ethtypes, ethprocs, stintjson, ethhexstrings
@ -286,9 +286,16 @@ proc parseContract(body: NimNode): seq[InterfaceObject] =
macro contract(cname: untyped, body: untyped): untyped = macro contract(cname: untyped, body: untyped): untyped =
var objects = parseContract(body) var objects = parseContract(body)
result = newStmtList() result = newStmtList()
let address = ident "address"
result.add quote do: result.add quote do:
type 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: for obj in objects:
if obj.kind == function: if obj.kind == function:
echo obj.functionObject.outputs echo obj.functionObject.outputs
@ -328,7 +335,8 @@ macro contract(cname: untyped, body: untyped): untyped =
procDef[6].add quote do: procDef[6].add quote do:
var cc: EthCall var cc: EthCall
cc.source = some(`senderName`.address) 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`) cc.data = some("0x" & ($keccak_256.digest(`signature`))[0..<8].toLower & `encodedParams`)
let response = waitFor `client`.eth_call(cc, "latest") let response = waitFor `client`.eth_call(cc, "latest")
return response return response
@ -336,7 +344,8 @@ macro contract(cname: untyped, body: untyped): untyped =
procDef[6].add quote do: procDef[6].add quote do:
var cc: EthSend var cc: EthSend
cc.source = `senderName`.address 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` cc.data = "0x" & ($keccak_256.digest(`signature`))[0..<8].toLower & `encodedParams`
let response = waitFor `client`.eth_sendTransaction(cc) let response = waitFor `client`.eth_sendTransaction(cc)
return response return response
@ -393,7 +402,26 @@ macro toAddress(input: string): untyped =
ident "byte" 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( echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).getBalance(
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0") 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( echo toHex(x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).sendCoin(
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0"), fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0"),
100000.to(Stuint[256]) 256.to(Stuint[256])
)) ))
echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).getBalance( echo x.sender("127.0.0.1", 8545, "90f8bf6a479f320ead074411a4b0e7944ea8c9c1".toAddress).getBalance(
fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0") fromHex(Stuint[256], "ffcf8fdee72ac11b5c542428b35eef5769c409f0")
) )
#echo "0x" & $keccak_256.digest("Transfer(address,address,uint256)") #echo "0x" & $keccak_256.digest("Transfer(address,address,uint256)")
joinThreads([thr])