abi decoding of simple custom errors
Only supports errors without arguments for now
This commit is contained in:
parent
875900b493
commit
6b57e56a39
|
@ -0,0 +1,17 @@
|
||||||
|
import pkg/contractabi/selector
|
||||||
|
import ./basics
|
||||||
|
|
||||||
|
type SolidityError* = object of EthersError
|
||||||
|
|
||||||
|
{.push raises:[].}
|
||||||
|
|
||||||
|
template errors*(types) {.pragma.}
|
||||||
|
|
||||||
|
func decode*[E: SolidityError](_: type E, data: seq[byte]): ?!(ref E) =
|
||||||
|
const name = $E
|
||||||
|
const selector = selector(name, typeof(()))
|
||||||
|
if data.len < 4:
|
||||||
|
return failure "unable to decode " & name & ": signature too short"
|
||||||
|
if selector.toArray[0..<4] != data[0..<4]:
|
||||||
|
return failure "unable to decode " & name & ": signature doesn't match"
|
||||||
|
success (ref E)()
|
|
@ -7,5 +7,6 @@ import ./testWallet
|
||||||
import ./testTesting
|
import ./testTesting
|
||||||
import ./testErc20
|
import ./testErc20
|
||||||
import ./testGasEstimation
|
import ./testGasEstimation
|
||||||
|
import ./testErrorDecoding
|
||||||
|
|
||||||
{.warning[UnusedImport]:off.}
|
{.warning[UnusedImport]:off.}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import std/unittest
|
||||||
|
import pkg/questionable/results
|
||||||
|
import pkg/ethers/errors
|
||||||
|
|
||||||
|
suite "Decoding of custom errors":
|
||||||
|
|
||||||
|
type SimpleError = object of SolidityError
|
||||||
|
|
||||||
|
test "decodes a simple error":
|
||||||
|
let decoded = SimpleError.decode(@[0xc2'u8, 0xbb, 0x94, 0x7c])
|
||||||
|
check decoded is ?!(ref SimpleError)
|
||||||
|
check decoded.isSuccess
|
||||||
|
check (!decoded) != nil
|
||||||
|
|
||||||
|
test "returns failure when decoding fails":
|
||||||
|
let invalid = @[0xc2'u8, 0xbb, 0x94, 0x0] # last byte is wrong
|
||||||
|
let decoded = SimpleError.decode(invalid)
|
||||||
|
check decoded.isFailure
|
||||||
|
|
||||||
|
test "returns failure when data is less than 4 bytes":
|
||||||
|
let invalid = @[0xc2'u8, 0xbb, 0x94]
|
||||||
|
let decoded = SimpleError.decode(invalid)
|
||||||
|
check decoded.isFailure
|
||||||
|
|
||||||
|
test "decoding only works for SolidityErrors":
|
||||||
|
type InvalidError = ref object of CatchableError
|
||||||
|
const works = compiles:
|
||||||
|
InvalidError.decode(@[0x1'u8, 0x2, 0x3, 0x4])
|
||||||
|
check not works
|
||||||
|
|
Loading…
Reference in New Issue