Fixed fixed encoding, inputs/outputs parsing
This commit is contained in:
parent
58d78cfa7f
commit
817c819847
|
@ -52,7 +52,7 @@ contract MetaCoin {
|
||||||
contract(MetaCoin):
|
contract(MetaCoin):
|
||||||
proc sendCoin(receiver: Address, amount: Uint256): Bool
|
proc sendCoin(receiver: Address, amount: Uint256): Bool
|
||||||
proc getBalance(address: Address): Uint256 {.view.}
|
proc getBalance(address: Address): Uint256 {.view.}
|
||||||
proc Transfer(fromAddr: indexed[Address], toAddr: indexed[Address], value: Uint256) {.event.}
|
proc Transfer(fromAddr, toAddr: indexed[Address], value: Uint256) {.event.}
|
||||||
proc BlaBla(fromAddr: indexed[Address]) {.event.}
|
proc BlaBla(fromAddr: indexed[Address]) {.event.}
|
||||||
|
|
||||||
const MetaCoinCode = "608060405234801561001057600080fd5b5032600090815260208190526040902061271090556101c2806100346000396000f30060806040526004361061004b5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166390b98a118114610050578063f8b2cb4f14610095575b600080fd5b34801561005c57600080fd5b5061008173ffffffffffffffffffffffffffffffffffffffff600435166024356100d5565b604080519115158252519081900360200190f35b3480156100a157600080fd5b506100c373ffffffffffffffffffffffffffffffffffffffff6004351661016e565b60408051918252519081900360200190f35b336000908152602081905260408120548211156100f457506000610168565b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260208190526040902054905600a165627a7a72305820000313ec0ebbff4ffefbe79d615d0ab019d8566100c40eb95a4eee617a87d1090029"
|
const MetaCoinCode = "608060405234801561001057600080fd5b5032600090815260208190526040902061271090556101c2806100346000396000f30060806040526004361061004b5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166390b98a118114610050578063f8b2cb4f14610095575b600080fd5b34801561005c57600080fd5b5061008173ffffffffffffffffffffffffffffffffffffffff600435166024356100d5565b604080519115158252519081900360200190f35b3480156100a157600080fd5b506100c373ffffffffffffffffffffffffffffffffffffffff6004351661016e565b60408051918252519081900360200190f35b336000908152602081905260408120548211156100f457506000610168565b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260208190526040902054905600a165627a7a72305820000313ec0ebbff4ffefbe79d615d0ab019d8566100c40eb95a4eee617a87d1090029"
|
||||||
|
|
File diff suppressed because one or more lines are too long
147
web3.nim
147
web3.nim
|
@ -138,7 +138,9 @@ func decode*[N](input: string, offset: int, to: var Stint[N]): int =
|
||||||
meaningfulLen
|
meaningfulLen
|
||||||
|
|
||||||
func fixedEncode(a: openarray[byte]): EncodeResult =
|
func fixedEncode(a: openarray[byte]): EncodeResult =
|
||||||
result = (dynamic: false, data: "00".repeat(32 - a.len mod 32) & byteutils.toHex(a))
|
var padding = a.len mod 32
|
||||||
|
if padding != 0: padding = 32 - padding
|
||||||
|
result = (dynamic: false, data: "00".repeat(padding) & byteutils.toHex(a))
|
||||||
|
|
||||||
func encode*[N](b: FixedBytes[N]): EncodeResult = fixedEncode(array[N, byte](b))
|
func encode*[N](b: FixedBytes[N]): EncodeResult = fixedEncode(array[N, byte](b))
|
||||||
func encode*(b: Address): EncodeResult = fixedEncode(array[20, byte](b))
|
func encode*(b: Address): EncodeResult = fixedEncode(array[20, byte](b))
|
||||||
|
@ -175,7 +177,8 @@ func fromHex*(x: type Address, s: string): Address {.inline.} =
|
||||||
|
|
||||||
func decodeFixed(input: string, offset: int, to: var openarray[byte]): int =
|
func decodeFixed(input: string, offset: int, to: var openarray[byte]): int =
|
||||||
let meaningfulLen = to.len * 2
|
let meaningfulLen = to.len * 2
|
||||||
let padding = (32 - to.len mod 32) * 2
|
var padding = to.len mod 32
|
||||||
|
if padding != 0: padding = (32 - padding) * 2
|
||||||
let offset = offset + padding
|
let offset = offset + padding
|
||||||
fromHexAux(input[offset .. offset + meaningfulLen - 1], to)
|
fromHexAux(input[offset .. offset + meaningfulLen - 1], to)
|
||||||
meaningfulLen + padding
|
meaningfulLen + padding
|
||||||
|
@ -219,7 +222,7 @@ template typeSignature(T: typedesc): string =
|
||||||
elif T is DynamicBytes:
|
elif T is DynamicBytes:
|
||||||
"bytes"
|
"bytes"
|
||||||
elif T is FixedBytes:
|
elif T is FixedBytes:
|
||||||
"byte" & $T.N
|
"bytes" & $T.N
|
||||||
elif T is StUint:
|
elif T is StUint:
|
||||||
"uint" & $T.bits
|
"uint" & $T.bits
|
||||||
elif T is Address:
|
elif T is Address:
|
||||||
|
@ -369,23 +372,13 @@ type
|
||||||
function, constructor, event
|
function, constructor, event
|
||||||
MutabilityKind = enum
|
MutabilityKind = enum
|
||||||
pure, view, nonpayable, payable
|
pure, view, nonpayable, payable
|
||||||
SequenceKind = enum
|
|
||||||
single, fixed, dynamic
|
|
||||||
FunctionInputOutput = object
|
FunctionInputOutput = object
|
||||||
name: string
|
name: string
|
||||||
typ: string
|
typ: NimNode
|
||||||
case sequenceKind: SequenceKind
|
|
||||||
of single, dynamic: discard
|
|
||||||
of fixed:
|
|
||||||
count: int
|
|
||||||
EventInput = object
|
EventInput = object
|
||||||
name: string
|
name: string
|
||||||
typ: string
|
typ: NimNode
|
||||||
indexed: bool
|
indexed: bool
|
||||||
case sequenceKind: SequenceKind
|
|
||||||
of single, dynamic: discard
|
|
||||||
of fixed:
|
|
||||||
count: int
|
|
||||||
FunctionObject = object
|
FunctionObject = object
|
||||||
name: string
|
name: string
|
||||||
stateMutability: MutabilityKind
|
stateMutability: MutabilityKind
|
||||||
|
@ -412,7 +405,7 @@ proc getSignature(function: FunctionObject | EventObject): NimNode =
|
||||||
result = newCall(bindSym"joinStrings")
|
result = newCall(bindSym"joinStrings")
|
||||||
result.add(newLit(function.name & "("))
|
result.add(newLit(function.name & "("))
|
||||||
for i, input in function.inputs:
|
for i, input in function.inputs:
|
||||||
result.add(newCall(bindSym"typeSignature", ident input.typ))
|
result.add(newCall(bindSym"typeSignature", input.typ))
|
||||||
if i != function.inputs.high:
|
if i != function.inputs.high:
|
||||||
result.add(newLit(","))
|
result.add(newLit(","))
|
||||||
result.add(newLit(")"))
|
result.add(newLit(")"))
|
||||||
|
@ -432,90 +425,40 @@ proc addAddressAndSignatureToOptions(options: JsonNode, address: Address, signat
|
||||||
|
|
||||||
proc parseContract(body: NimNode): seq[InterfaceObject] =
|
proc parseContract(body: NimNode): seq[InterfaceObject] =
|
||||||
proc parseOutputs(outputNode: NimNode): seq[FunctionInputOutput] =
|
proc parseOutputs(outputNode: NimNode): seq[FunctionInputOutput] =
|
||||||
#if outputNode.kind == nnkIdent:
|
result.add FunctionInputOutput(typ: (if outputNode.kind == nnkEmpty: ident"void" else: outputNode))
|
||||||
# result.add FunctionInputOutput(
|
|
||||||
# name: "",
|
|
||||||
# typ: $outputNode.ident
|
|
||||||
# )
|
|
||||||
case outputNode.kind:
|
|
||||||
of nnkBracketExpr:
|
|
||||||
result.add FunctionInputOutput(
|
|
||||||
name: "",
|
|
||||||
typ: $outputNode[0].ident,
|
|
||||||
sequenceKind: if outputNode.len == 1:
|
|
||||||
dynamic
|
|
||||||
else:
|
|
||||||
fixed
|
|
||||||
)
|
|
||||||
if outputNode.len == 2:
|
|
||||||
result[^1].count = outputNode[1].intVal.int
|
|
||||||
of nnkIdent:
|
|
||||||
result.add FunctionInputOutput(
|
|
||||||
name: "",
|
|
||||||
typ: $outputNode.ident,
|
|
||||||
sequenceKind: single
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
proc parseInputs(inputNodes: NimNode): seq[FunctionInputOutput] =
|
proc parseInputs(inputNodes: NimNode): seq[FunctionInputOutput] =
|
||||||
for i in 1..<inputNodes.len:
|
for i in 1..<inputNodes.len:
|
||||||
let input = inputNodes[i]
|
let input = inputNodes[i]
|
||||||
if input.kind == nnkIdentDefs:
|
input.expectKind(nnkIdentDefs)
|
||||||
when defined(debug):
|
let typ = input[^2]
|
||||||
echo input.repr
|
for j in 0 .. input.len - 3:
|
||||||
# echo input.treerepr
|
let arg = input[j]
|
||||||
if input[1].kind == nnkBracketExpr:
|
result.add(FunctionInputOutput(
|
||||||
result.add FunctionInputOutput(
|
name: $arg,
|
||||||
name: $input[0].ident,
|
typ: typ,
|
||||||
typ: $input[1][0].ident,
|
))
|
||||||
sequenceKind: if input[1].len == 1:
|
|
||||||
dynamic
|
|
||||||
else:
|
|
||||||
fixed
|
|
||||||
)
|
|
||||||
if input[1].len == 2:
|
|
||||||
result[^1].count = input[1][1].intVal.int
|
|
||||||
else:
|
|
||||||
result.add FunctionInputOutput(
|
|
||||||
name: $input[0].ident,
|
|
||||||
typ: $input[1].ident,
|
|
||||||
sequenceKind: single
|
|
||||||
)
|
|
||||||
proc parseEventInputs(inputNodes: NimNode): seq[EventInput] =
|
proc parseEventInputs(inputNodes: NimNode): seq[EventInput] =
|
||||||
for i in 1..<inputNodes.len:
|
for i in 1..<inputNodes.len:
|
||||||
let input = inputNodes[i]
|
let input = inputNodes[i]
|
||||||
if input.kind == nnkIdentDefs:
|
input.expectKind(nnkIdentDefs)
|
||||||
case input[1].kind:
|
let typ = input[^2]
|
||||||
of nnkIdent:
|
for j in 0 .. input.len - 3:
|
||||||
result.add EventInput(
|
let arg = input[j]
|
||||||
name: $input[0].ident,
|
case typ.kind:
|
||||||
typ: $input[1].ident,
|
|
||||||
indexed: false
|
|
||||||
)
|
|
||||||
of nnkBracketExpr:
|
of nnkBracketExpr:
|
||||||
#doAssert($input[1][0].ident == "indexed",
|
if $typ[0] == "indexed":
|
||||||
# "Only `indexed` is allowed as option for event inputs")
|
|
||||||
if $input[1][0].ident == "indexed":
|
|
||||||
result.add EventInput(
|
result.add EventInput(
|
||||||
name: $input[0].ident,
|
name: $arg,
|
||||||
typ: $input[1][1].ident,
|
typ: typ[1],
|
||||||
indexed: true
|
indexed: true
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result.add EventInput(
|
result.add EventInput(name: $arg, typ: typ)
|
||||||
name: $input[0].ident,
|
|
||||||
typ: $input[1][0].ident,
|
|
||||||
indexed: false,
|
|
||||||
sequenceKind: if input[1].len == 1:
|
|
||||||
dynamic
|
|
||||||
else:
|
|
||||||
fixed
|
|
||||||
)
|
|
||||||
if input[1].len != 1:
|
|
||||||
result[^1].count = input[1][1].intVal.int
|
|
||||||
else:
|
else:
|
||||||
doAssert(false,
|
result.add EventInput(name: $arg, typ: typ)
|
||||||
"Can't have anything but ident or bracket expression here")
|
|
||||||
when defined(debug):
|
when defined(debug):
|
||||||
echo body.treeRepr
|
echo body.treeRepr
|
||||||
var
|
var
|
||||||
|
@ -599,7 +542,7 @@ macro contract*(cname: untyped, body: untyped): untyped =
|
||||||
output = if obj.functionObject.outputs.len != 1:
|
output = if obj.functionObject.outputs.len != 1:
|
||||||
ident "void"
|
ident "void"
|
||||||
else:
|
else:
|
||||||
ident obj.functionObject.outputs[0].typ
|
obj.functionObject.outputs[0].typ
|
||||||
var
|
var
|
||||||
encodedParams = genSym(nskVar)#newLit("")
|
encodedParams = genSym(nskVar)#newLit("")
|
||||||
offset = genSym(nskVar)
|
offset = genSym(nskVar)
|
||||||
|
@ -619,13 +562,8 @@ macro contract*(cname: untyped, body: untyped): untyped =
|
||||||
`offset` += (if encoding.dynamic:
|
`offset` += (if encoding.dynamic:
|
||||||
32
|
32
|
||||||
else:
|
else:
|
||||||
encoding.data.len)
|
encoding.data.len div 2)
|
||||||
`encodings`.add encoding
|
`encodings`.add encoding
|
||||||
#encodedParams = nnkInfix.newTree(
|
|
||||||
# ident "&",
|
|
||||||
# encodedParams,
|
|
||||||
# nnkCall.newTree(ident "encode", ident input.name)
|
|
||||||
#)
|
|
||||||
encoder.add quote do:
|
encoder.add quote do:
|
||||||
for encoding in `encodings`:
|
for encoding in `encodings`:
|
||||||
if encoding.dynamic:
|
if encoding.dynamic:
|
||||||
|
@ -642,20 +580,7 @@ macro contract*(cname: untyped, body: untyped): untyped =
|
||||||
for input in obj.functionObject.inputs:
|
for input in obj.functionObject.inputs:
|
||||||
procDef[3].add nnkIdentDefs.newTree(
|
procDef[3].add nnkIdentDefs.newTree(
|
||||||
ident input.name,
|
ident input.name,
|
||||||
(case input.sequenceKind:
|
input.typ,
|
||||||
of single: ident input.typ
|
|
||||||
of dynamic: nnkBracketExpr.newTree(ident "seq", ident input.typ)
|
|
||||||
of fixed:
|
|
||||||
nnkBracketExpr.newTree(
|
|
||||||
ident "array",
|
|
||||||
nnkInfix.newTree(
|
|
||||||
ident "..",
|
|
||||||
newLit(0),
|
|
||||||
newLit(input.count)
|
|
||||||
),
|
|
||||||
ident input.typ
|
|
||||||
)
|
|
||||||
),
|
|
||||||
newEmptyNode()
|
newEmptyNode()
|
||||||
)
|
)
|
||||||
procDef[6].add quote do:
|
procDef[6].add quote do:
|
||||||
|
@ -686,14 +611,14 @@ macro contract*(cname: untyped, body: untyped): untyped =
|
||||||
for input in obj.eventObject.inputs:
|
for input in obj.eventObject.inputs:
|
||||||
let param = nnkIdentDefs.newTree(
|
let param = nnkIdentDefs.newTree(
|
||||||
ident input.name,
|
ident input.name,
|
||||||
ident input.typ,
|
input.typ,
|
||||||
newEmptyNode()
|
newEmptyNode()
|
||||||
)
|
)
|
||||||
params.add param
|
params.add param
|
||||||
paramsWithRawData.add param
|
paramsWithRawData.add param
|
||||||
let
|
let
|
||||||
argument = genSym(nskVar)
|
argument = genSym(nskVar)
|
||||||
kind = ident input.typ
|
kind = input.typ
|
||||||
if input.indexed:
|
if input.indexed:
|
||||||
argParseBody.add quote do:
|
argParseBody.add quote do:
|
||||||
var `argument`: `kind`
|
var `argument`: `kind`
|
||||||
|
|
Loading…
Reference in New Issue