mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
Changed mimes and implemented the 'encodeType' function for EIP-712
This commit is contained in:
parent
a849bb1a70
commit
3d0e8d37fe
7 changed files with 307 additions and 45 deletions
|
|
@ -14,3 +14,51 @@ t=2018-10-13T05:44:06-0700 lvl=info msg=SignTypedData api=signer type=response d
|
||||||
t=2018-10-13T05:46:53-0700 lvl=info msg=Configured api=signer audit log=audit.log
|
t=2018-10-13T05:46:53-0700 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
t=2018-10-13T05:46:58-0700 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:61694\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
t=2018-10-13T05:46:58-0700 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:61694\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
t=2018-10-13T05:46:58-0700 lvl=info msg=SignTypedData api=signer type=response data= error=nil
|
t=2018-10-13T05:46:58-0700 lvl=info msg=SignTypedData api=signer type=response data= error=nil
|
||||||
|
t=2018-10-14T21:00:04+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:00:06+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56799\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[type:address name:wallet]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB name:Bob] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:00:06+0100 lvl=info msg=SignTypedData api=signer type=response data= error="Couldn't decode types of EIP712Domain"
|
||||||
|
t=2018-10-14T21:00:50+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:01:02+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56810\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[type:uint256 name:chainId] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:01:02+0100 lvl=info msg=SignTypedData api=signer type=response data= error="Couldn't decode types of EIP712Domain"
|
||||||
|
t=2018-10-14T21:01:39+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:01:53+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56823\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 name:Alice] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:01:53+0100 lvl=info msg=SignTypedData api=signer type=response data= error="Couldn't decode types of EIP712Domain"
|
||||||
|
t=2018-10-14T21:11:30+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:11:33+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56899\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[type:uint256 name:chainId] map[name:verifyingContract type:address]] Person:[map[type:string name:name] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:11:33+0100 lvl=info msg=SignTypedData api=signer type=response data= error="Couldn't decode types of EIP712Domain"
|
||||||
|
t=2018-10-14T21:15:28+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:15:34+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56968\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:15:34+0100 lvl=info msg=SignTypedData api=signer type=response data= error="Couldn't decode types of EIP712Domain"
|
||||||
|
t=2018-10-14T21:17:53+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:17:57+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:56991\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[type:string name:name] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:17:57+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T21:18:32+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:18:36+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57006\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[type:address name:wallet]] Mail:[map[type:Person name:from] map[name:to type:Person] map[type:string name:contents]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:18:36+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T21:18:59+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:19:00+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57017\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]] EIP712Domain:[map[name:name type:string] map[type:string name:version] map[name:chainId type:uint256] map[name:verifyingContract type:address]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:19:00+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T21:30:19+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:30:29+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57188\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:{neg:false abs:[1]} VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB name:Bob] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:30:29+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T21:51:40+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T21:51:42+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57392\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[type:Person name:from] map[name:to type:Person] map[name:contents type:string]] EIP712Domain:[map[name:name type:string] map[type:string name:version] map[name:chainId type:uint256] map[name:verifyingContract type:address]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB name:Bob] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T21:51:42+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T22:16:07+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T22:16:14+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57602\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]] EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[contents:Hello, Bob! from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB]]}"
|
||||||
|
t=2018-10-14T22:16:14+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T22:18:31+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T22:18:35+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57653\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[type:Person name:from] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T22:18:35+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-14T22:20:47+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-14T22:20:50+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:57669\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]] EIP712Domain:[map[name:name type:string] map[type:string name:version] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-14T22:20:50+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-15T03:11:09+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-15T03:11:17+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:50605\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[type:string name:name] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob! from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21]]}"
|
||||||
|
t=2018-10-15T03:11:17+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-15T03:12:01+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-15T03:12:04+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:50618\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[type:address name:wallet]] Mail:[map[name:from type:Person] map[name:to type:Person] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[name:Bob wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-15T03:12:04+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
t=2018-10-15T03:14:48+0100 lvl=info msg=Configured api=signer audit log=audit.log
|
||||||
|
t=2018-10-15T03:15:25+0100 lvl=info msg=SignTypedData api=signer type=request metadata="{\"remote\":\"127.0.0.1:50635\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data="{Types:map[EIP712Domain:[map[name:name type:string] map[name:version type:string] map[name:chainId type:uint256] map[name:verifyingContract type:address]] Person:[map[name:name type:string] map[name:wallet type:address]] Mail:[map[name:from type:Person] map[type:Person name:to] map[name:contents type:string]]] PrimaryType:Mail Domain:{Name:Ether Mail Version:1 ChainId:+1 VerifyingContract:[204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204 204] Salt:0x} Message:map[from:map[name:Alice wallet:0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21] to:map[wallet:0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB name:Bob] contents:Hello, Bob!]}"
|
||||||
|
t=2018-10-15T03:15:25+0100 lvl=info msg=SignTypedData api=signer type=response data=deadbeef error=nil
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@
|
||||||
|
|
||||||
#### 5.0.0
|
#### 5.0.0
|
||||||
|
|
||||||
* The external `account_EcRecover`-method was added again.
|
* The external `account_EcRecover`-method was reimplemented.
|
||||||
* The external method `account_sign(address, data)` was replaced with `account_signData(contentType, address, data)`.
|
* The external method `account_sign(address, data)` was replaced with `account_signData(contentType, address, data)`.
|
||||||
The addition of `contentType` makes it possible to use the method for different types of objects, such as:
|
The addition of `contentType` makes it possible to use the method for different types of objects, such as:
|
||||||
* signing data with an intended validator (not yet implemented)
|
* signing data with an intended validator (not yet implemented)
|
||||||
* signing clique headers,
|
* signing clique headers,
|
||||||
* signing plain personal messages,
|
* signing plain personal messages,
|
||||||
* The external method `account_signTypedData` implements [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) and makes it possible to sign typed data.
|
* The external method `account_signTypedData` [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) and makes it possible to sign typed data.
|
||||||
* signing structured data adhering to [EIP-712](https://eips.ethereum.org/EIPS/eip-712) (not yet implemented)
|
|
||||||
|
|
||||||
#### 4.0.0
|
#### 4.0.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -666,6 +668,8 @@ func testExternalUI(api *core.SignerAPI) {
|
||||||
checkErr("SignTransaction", err)
|
checkErr("SignTransaction", err)
|
||||||
_, err = api.SignData(ctx, "text/plain", common.MixedcaseAddress{}, common.Hex2Bytes("01020304"))
|
_, err = api.SignData(ctx, "text/plain", common.MixedcaseAddress{}, common.Hex2Bytes("01020304"))
|
||||||
checkErr("SignData", err)
|
checkErr("SignData", err)
|
||||||
|
_, err = api.SignTypedData(ctx, common.MixedcaseAddress{}, core.TypedData{})
|
||||||
|
checkErr("SignTypedData", err)
|
||||||
_, err = api.List(ctx)
|
_, err = api.List(ctx)
|
||||||
checkErr("List", err)
|
checkErr("List", err)
|
||||||
_, err = api.New(ctx)
|
_, err = api.New(ctx)
|
||||||
|
|
|
||||||
|
|
@ -208,4 +208,4 @@ type GasEstimator interface {
|
||||||
// pending state.
|
// pending state.
|
||||||
type PendingStateEventer interface {
|
type PendingStateEventer interface {
|
||||||
SubscribePendingTransactions(ctx context.Context, ch chan<- *types.Transaction) (Subscription, error)
|
SubscribePendingTransactions(ctx context.Context, ch chan<- *types.Transaction) (Subscription, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,21 +117,21 @@ type SigFormat struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TextPlain = SigFormat{
|
|
||||||
"text/plain",
|
|
||||||
0x00,
|
|
||||||
}
|
|
||||||
TextValidator = SigFormat{
|
TextValidator = SigFormat{
|
||||||
"text/validator",
|
"text/validator",
|
||||||
0x01,
|
0x00,
|
||||||
}
|
}
|
||||||
DataTyped = SigFormat{
|
DataTyped = SigFormat{
|
||||||
"data/typed",
|
"data/typed",
|
||||||
0x45,
|
0x01,
|
||||||
}
|
}
|
||||||
ApplicationClique = SigFormat{
|
ApplicationClique = SigFormat{
|
||||||
"application/clique",
|
"application/clique",
|
||||||
0x90,
|
0x02,
|
||||||
|
}
|
||||||
|
TextPlain = SigFormat{
|
||||||
|
"text/plain",
|
||||||
|
0x45,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -610,22 +610,6 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, data hexutil.
|
||||||
|
|
||||||
sighash, msg := signTextPlain(data)
|
sighash, msg := signTextPlain(data)
|
||||||
req = &SignDataRequest{Rawdata: data, Message: msg, Hash: sighash, ContentType: mediaType}
|
req = &SignDataRequest{Rawdata: data, Message: msg, Hash: sighash, ContentType: mediaType}
|
||||||
//case DataTyped.Mime:
|
|
||||||
// // Typed data according to EIP712:
|
|
||||||
// //
|
|
||||||
// // hash = keccak256("\x19${byteVersion}${domainSeparator}${hashStruct(message)}")
|
|
||||||
// fmt.Println("Did we get here, chief? #1")
|
|
||||||
// typedData := TypedData{}
|
|
||||||
// if err := rlp.DecodeBytes(data, typedData); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// fmt.Println("Did we get here, chief? #2")
|
|
||||||
// sighash, err := signTypedData(context.Background(), typedData)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// msg := fmt.Sprintf("Typed data domain %s", typedData.Domain)
|
|
||||||
// req = &SignDataRequest{Rawdata: data, Message: msg, Hash: sighash, ContentType: mediaType}
|
|
||||||
case ApplicationClique.Mime:
|
case ApplicationClique.Mime:
|
||||||
// Clique is the Ethereum PoA standard
|
// Clique is the Ethereum PoA standard
|
||||||
header := &types.Header{}
|
header := &types.Header{}
|
||||||
|
|
@ -664,7 +648,7 @@ func signTextWithValidator(data []byte) ([]byte, string) {
|
||||||
return crypto.Keccak256([]byte(msg)), msg
|
return crypto.Keccak256([]byte(msg)), msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCliqueHeader returns the hash which is used as input for the proof-of-authority
|
// signCliqueHeader returns the hash which is used as input for the proof-of-authority
|
||||||
// signing. It is the hash of the entire header apart from the 65 byte signature
|
// signing. It is the hash of the entire header apart from the 65 byte signature
|
||||||
// contained at the end of the extra data.
|
// contained at the end of the extra data.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Specs
|
# Specs
|
||||||
`encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x45" ‖ domainSeparator ‖ hashStruct(message)`
|
`encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)`
|
||||||
- data adheres to 𝕊, a structure defined in the rigorous eip-712
|
- data adheres to 𝕊, a structure defined in the rigorous eip-712
|
||||||
- `\x45` is needed to comply with EIP-191
|
- `\x00` is needed to comply with EIP-191
|
||||||
- `domainSeparator` and `hashStruct` are defined below
|
- `domainSeparator` and `hashStruct` are defined below
|
||||||
|
|
||||||
## A) domainSeparator
|
## A) domainSeparator
|
||||||
|
|
@ -26,6 +26,8 @@ Struct named `EIP712Domain` with one or more of the below fields:
|
||||||
- each member is written as `type ‖ " " ‖ name`
|
- each member is written as `type ‖ " " ‖ name`
|
||||||
- encodings cascade down and are sorted by name
|
- encodings cascade down and are sorted by name
|
||||||
|
|
||||||
|
Example: `Mail(Person from,Person to,string contents)Person(string name,address wallet)`
|
||||||
|
|
||||||
### ii) encodeData
|
### ii) encodeData
|
||||||
- `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`
|
- `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`
|
||||||
- each encoded member is 32-byte long
|
- each encoded member is 32-byte long
|
||||||
|
|
@ -52,7 +54,7 @@ Struct named `EIP712Domain` with one or more of the below fields:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "account_signStructuredData",
|
"method": "account_signTypedData",
|
||||||
"params": [
|
"params": [
|
||||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||||
{
|
{
|
||||||
|
|
@ -131,4 +133,4 @@ Struct named `EIP712Domain` with one or more of the below fields:
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
|
"result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,259 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TypedData struct {
|
type TypedData struct {
|
||||||
Types map[string] interface{} `json:"types"`
|
Types EIP712Types `json:"types"`
|
||||||
PrimaryType string `json:"primaryType"`
|
PrimaryType string `json:"primaryType"`
|
||||||
Domain EIP712Domain `json:"domain"`
|
Domain EIP712Domain `json:"domain"`
|
||||||
Message map[string] interface{} `json:"message"`
|
Message EIP712Message `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EIP712Types map[string][]map[string]string
|
||||||
|
|
||||||
|
type EIP712TypePriority struct {
|
||||||
|
Type string
|
||||||
|
Value uint
|
||||||
}
|
}
|
||||||
|
|
||||||
type EIP712Domain struct {
|
type EIP712Domain struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
ChainId big.Int `json:"chainId"`
|
ChainId *big.Int `json:"chainId"`
|
||||||
VerifyingContract common.Address `json:"verifyingContract"`
|
VerifyingContract common.Address `json:"verifyingContract"`
|
||||||
Salt hexutil.Bytes `json:"salt"`
|
Salt hexutil.Bytes `json:"salt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EIP712Message map[string]interface{}
|
||||||
|
|
||||||
// Typed data according to EIP712
|
// Typed data according to EIP712
|
||||||
//
|
//
|
||||||
// hash = keccak256("\x19${byteVersion}${domainSeparator}${hashStruct(message)}")
|
// hash = keccak256("\x19${byteVersion}${domainSeparator}${hashStruct(message)}")
|
||||||
func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAddress, data TypedData) (hexutil.Bytes, error) {
|
func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAddress, data TypedData) (hexutil.Bytes, error) {
|
||||||
fmt.Println("addr", addr)
|
if err := data.Domain.IsValid(); err != nil {
|
||||||
//fmt.Println("data", data)
|
return nil, err
|
||||||
fmt.Println("data.Domain", data.Domain)
|
}
|
||||||
return common.Hex2Bytes("0xdeadbeef"), nil
|
if data.PrimaryType == "" {
|
||||||
|
return nil, fmt.Errorf("primary type undefined")
|
||||||
|
}
|
||||||
|
|
||||||
|
domainTypes := EIP712Types{
|
||||||
|
"EIP712Domain": data.Types["EIP712Domain"],
|
||||||
|
}
|
||||||
|
domainSeparator, err := hashStruct(domainTypes, data.Domain.Values(), "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(data.Types, "EIP712Domain")
|
||||||
|
typedDataHash, err := hashStruct(data.Types, data.Message, data.PrimaryType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("domainSeparator", domainSeparator.String())
|
||||||
|
fmt.Println("typedDataHash", typedDataHash.String())
|
||||||
|
return common.FromHex("0xdeadbeef"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// `encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)`
|
||||||
|
func hashStruct(types EIP712Types, message EIP712Message, primaryType string) (common.Hash, error) {
|
||||||
|
if primaryType != "" {
|
||||||
|
if types[primaryType] == nil {
|
||||||
|
return common.Hash{}, fmt.Errorf("primaryType specified but undefined")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeEncoding, err := encodeType(types, primaryType)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
typeHash := hex.EncodeToString(crypto.Keccak256([]byte(typeEncoding)))
|
||||||
|
|
||||||
|
dataEncoding, err := encodeData(message)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
dataHash := hex.EncodeToString(crypto.Keccak256([]byte(dataEncoding)))
|
||||||
|
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString(typeHash)
|
||||||
|
buffer.WriteString(dataHash)
|
||||||
|
hash := common.BytesToHash(crypto.Keccak256(buffer.Bytes()))
|
||||||
|
|
||||||
|
return hash, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeType transforms the given types into an encoding of the form
|
||||||
|
// `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"`
|
||||||
|
//
|
||||||
|
// Each member is written as `type ‖ " " ‖ name` encodings cascade down and are sorted by name
|
||||||
|
func encodeType(types EIP712Types, primaryType string) (string, error) {
|
||||||
|
var priorities = make(map[string]uint)
|
||||||
|
for key := range types {
|
||||||
|
priorities[key] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the priority for every new custom type discovered
|
||||||
|
update := func(typeKey string, typeVal string) {
|
||||||
|
priorities[typeVal]++
|
||||||
|
|
||||||
|
// Importantly, we also have to check for parent types to increment them too
|
||||||
|
for _, typeObj := range types[typeVal] {
|
||||||
|
_typeVal := typeObj["type"]
|
||||||
|
|
||||||
|
firstChar := []rune(_typeVal)[0]
|
||||||
|
if unicode.IsUpper(firstChar) {
|
||||||
|
priorities[_typeVal]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if referenced type has already been visited to optimise algo
|
||||||
|
visited := func(arr []string, val string) bool {
|
||||||
|
for _, elem := range arr {
|
||||||
|
if elem == val {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for typeKey, typeArr := range types {
|
||||||
|
var typeValArr []string
|
||||||
|
|
||||||
|
for _, typeObj := range typeArr {
|
||||||
|
typeVal := typeObj["type"]
|
||||||
|
if typeKey == typeVal {
|
||||||
|
return "", fmt.Errorf("type %s cannot reference itself", typeVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstChar := []rune(typeVal)[0]
|
||||||
|
if unicode.IsUpper(firstChar) {
|
||||||
|
if types[typeVal] != nil {
|
||||||
|
if !visited(typeValArr, typeVal) {
|
||||||
|
typeValArr = append(typeValArr, typeVal)
|
||||||
|
update(typeKey, typeVal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("referenced type %s is undefined", typeVal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !types.IsStandardType(typeVal) {
|
||||||
|
if types[typeVal] != nil {
|
||||||
|
return "", fmt.Errorf("Custom type %s must be capitalized", typeVal)
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("Unknown type %s", typeVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeValArr = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortedPriorities := types.SortByPriorityAndName(priorities)
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
for _, priority := range sortedPriorities {
|
||||||
|
typeKey := priority.Type
|
||||||
|
typeArr := types[typeKey]
|
||||||
|
|
||||||
|
buffer.WriteString(typeKey)
|
||||||
|
buffer.WriteString("(")
|
||||||
|
|
||||||
|
for _, typeObj := range typeArr {
|
||||||
|
buffer.WriteString(typeObj["type"])
|
||||||
|
buffer.WriteString(" ")
|
||||||
|
buffer.WriteString(typeObj["name"])
|
||||||
|
buffer.WriteString(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.Truncate(buffer.Len() - 1)
|
||||||
|
buffer.WriteString(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeData(values EIP712Message) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the given type is a standard type accepted by EIP-712
|
||||||
|
func (types *EIP712Types) IsStandardType(typeStr string) bool {
|
||||||
|
standardTypes := []string{
|
||||||
|
"array",
|
||||||
|
"address",
|
||||||
|
"boolean",
|
||||||
|
"bytes",
|
||||||
|
"string",
|
||||||
|
"struct",
|
||||||
|
"uint",
|
||||||
|
}
|
||||||
|
for _, val := range standardTypes {
|
||||||
|
if strings.HasPrefix(typeStr, val) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to sort types by priority and name. Priority is calculated b
|
||||||
|
// based upon the number of references.
|
||||||
|
func (types *EIP712Types) SortByPriorityAndName(input map[string]uint) []EIP712TypePriority {
|
||||||
|
var priorities []EIP712TypePriority
|
||||||
|
for key, val := range input {
|
||||||
|
priorities = append(priorities, EIP712TypePriority{key, val})
|
||||||
|
}
|
||||||
|
// Alphabetically
|
||||||
|
sort.Slice(priorities, func(i, j int) bool {
|
||||||
|
return priorities[i].Type < priorities[j].Type
|
||||||
|
})
|
||||||
|
// Priority
|
||||||
|
sort.Slice(priorities, func(i, j int) bool {
|
||||||
|
return priorities[i].Value > priorities[j].Value
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, priority := range priorities {
|
||||||
|
fmt.Printf("%s, Value %d\n", priority.Type, priority.Value)
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
return priorities
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the given domain is valid, i.e. contains at least the minimum viable keys and values
|
||||||
|
func (domain *EIP712Domain) IsValid() error {
|
||||||
|
if domain.ChainId == big.NewInt(0) {
|
||||||
|
return fmt.Errorf("chainId must be specified according to EIP-155")
|
||||||
|
}
|
||||||
|
|
||||||
|
if domain.Name == "" && domain.Version == "" && len(domain.VerifyingContract) == 0 && len(domain.Salt) == 0 {
|
||||||
|
return fmt.Errorf("domain undefined")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to return the values of a domain in the form of a golang map
|
||||||
|
func (domain *EIP712Domain) Values() map[string]interface{} {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": domain.Name,
|
||||||
|
"version": domain.Version,
|
||||||
|
"chainId": domain.Name,
|
||||||
|
"verifyingContract": domain.VerifyingContract,
|
||||||
|
"salt": domain.Salt,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue