mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
Added example RPC calls for account_signData and account_signTypedData
This commit is contained in:
parent
3be30e7101
commit
1a9cbe33bd
3 changed files with 117 additions and 28 deletions
|
|
@ -189,7 +189,9 @@ None
|
||||||
"method": "account_new",
|
"method": "account_new",
|
||||||
"params": []
|
"params": []
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
Response
|
||||||
|
```
|
||||||
{
|
{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
|
@ -222,7 +224,9 @@ None
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "account_list"
|
"method": "account_list"
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
Response
|
||||||
|
```
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
|
@ -285,8 +289,8 @@ Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"id": 2,
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": 67,
|
|
||||||
"error": {
|
"error": {
|
||||||
"code": -32000,
|
"code": -32000,
|
||||||
"message": "Request denied"
|
"message": "Request denied"
|
||||||
|
|
@ -298,6 +302,7 @@ Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"id": 67,
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "account_signTransaction",
|
"method": "account_signTransaction",
|
||||||
"params": [
|
"params": [
|
||||||
|
|
@ -311,8 +316,7 @@ Response
|
||||||
"data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
|
"data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
|
||||||
},
|
},
|
||||||
"safeSend(address)"
|
"safeSend(address)"
|
||||||
],
|
]
|
||||||
"id": 67
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Response
|
Response
|
||||||
|
|
@ -346,16 +350,18 @@ Bash example:
|
||||||
{"jsonrpc":"2.0","id":67,"result":{"raw":"0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","tx":{"nonce":"0x0","gasPrice":"0x1","gas":"0x333","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0","value":"0x0","input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012","v":"0x26","r":"0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e","s":"0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","hash":"0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"}}}
|
{"jsonrpc":"2.0","id":67,"result":{"raw":"0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","tx":{"nonce":"0x0","gasPrice":"0x1","gas":"0x333","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0","value":"0x0","input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012","v":"0x26","r":"0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e","s":"0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","hash":"0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### account_signData
|
### account_signData
|
||||||
|
|
||||||
#### Sign data
|
#### Sign data
|
||||||
Signs a chunk of data and returns the calculated signature.
|
Signs a chunk of data and returns the calculated signature.
|
||||||
|
|
||||||
#### Arguments
|
#### Arguments
|
||||||
- content type [string]: type of data to sign
|
- content type [string]: type of signed data
|
||||||
|
- `text/validator`: hex data with custom validator defined in a contract
|
||||||
|
- `application/clique`: [clique](https://github.com/ethereum/EIPs/issues/225) headers
|
||||||
|
- `text/plain`: simple hex data validated by `account_ecRecover`
|
||||||
- account [address]: account to sign with
|
- account [address]: account to sign with
|
||||||
- data [data]: data to sign
|
- data [object]: data to sign
|
||||||
|
|
||||||
#### Result
|
#### Result
|
||||||
- calculated signature [data]
|
- calculated signature [data]
|
||||||
|
|
@ -377,19 +383,115 @@ Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": 3,
|
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
"id": 3,
|
||||||
"result": "0x5b6693f153b48ec1c706ba4169960386dbaa6903e249cc79a8e6ddc434451d417e1e57327872c7f538beeb323c300afa9999a3d4a5de6caf3be0d5ef832b67ef1c"
|
"result": "0x5b6693f153b48ec1c706ba4169960386dbaa6903e249cc79a8e6ddc434451d417e1e57327872c7f538beeb323c300afa9999a3d4a5de6caf3be0d5ef832b67ef1c"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### account_signTypedData
|
||||||
|
|
||||||
|
#### Sign data
|
||||||
|
Signs a chunk of structured data conformant to [EIP712]([EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md)) and returns the calculated signature.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
- account [address]: account to sign with
|
||||||
|
- data [object]: data to sign
|
||||||
|
|
||||||
|
#### Result
|
||||||
|
- calculated signature [data]
|
||||||
|
|
||||||
|
#### Sample call
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 68,
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "account_signTypedData",
|
||||||
|
"params": [
|
||||||
|
"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
|
{
|
||||||
|
"types": {
|
||||||
|
"EIP712Domain": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chainId",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "verifyingContract",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Person": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wallet",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Mail": [
|
||||||
|
{
|
||||||
|
"name": "from",
|
||||||
|
"type": "Person"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "to",
|
||||||
|
"type": "Person"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contents",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primaryType": "Mail",
|
||||||
|
"domain": {
|
||||||
|
"name": "Ether Mail",
|
||||||
|
"version": "1",
|
||||||
|
"chainId": 1,
|
||||||
|
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"from": {
|
||||||
|
"name": "Cow",
|
||||||
|
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Bob",
|
||||||
|
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
|
||||||
|
},
|
||||||
|
"contents": "Hello, Bob!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Response
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### account_ecRecover
|
### account_ecRecover
|
||||||
|
|
||||||
#### Sign data
|
#### Sign data
|
||||||
Derive the address from the account that was used to sign data from the data and signature.
|
Derive the address from the account that was used to sign data with content type `text/plain` and the signature.
|
||||||
|
|
||||||
#### Arguments
|
#### Arguments
|
||||||
- content type [string]: type of signed data
|
|
||||||
- data [data]: data that was signed
|
- data [data]: data that was signed
|
||||||
- signature [data]: the signature to verify
|
- signature [data]: the signature to verify
|
||||||
|
|
||||||
|
|
@ -461,7 +563,7 @@ Response
|
||||||
},
|
},
|
||||||
"id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9",
|
"id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9",
|
||||||
"version": 3
|
"version": 3
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ The addition of `contentType` makes it possible to use the method for different
|
||||||
* 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` [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` implements [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) and makes it possible to sign typed data.
|
||||||
|
|
||||||
#### 4.0.0
|
#### 4.0.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,6 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, addr common.M
|
||||||
}
|
}
|
||||||
sighash, msg := SignTextValidator(validatorData)
|
sighash, msg := SignTextValidator(validatorData)
|
||||||
req = &SignDataRequest{Rawdata: validatorData, Message: msg, Hash: sighash, ContentType: mediaType}
|
req = &SignDataRequest{Rawdata: validatorData, Message: msg, Hash: sighash, ContentType: mediaType}
|
||||||
break
|
|
||||||
case ApplicationClique.Mime:
|
case ApplicationClique.Mime:
|
||||||
// Clique is the Ethereum PoA standard
|
// Clique is the Ethereum PoA standard
|
||||||
cliqueData, err := hexutil.Decode(data.(string))
|
cliqueData, err := hexutil.Decode(data.(string))
|
||||||
|
|
@ -192,7 +191,6 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, addr common.M
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("clique block %d [0x%x]", header.Number, header.Hash())
|
msg := fmt.Sprintf("clique block %d [0x%x]", header.Number, header.Hash())
|
||||||
req = &SignDataRequest{Rawdata: cliqueData, Message: msg, Hash: sighash, ContentType: mediaType}
|
req = &SignDataRequest{Rawdata: cliqueData, Message: msg, Hash: sighash, ContentType: mediaType}
|
||||||
break
|
|
||||||
case TextPlain.Mime:
|
case TextPlain.Mime:
|
||||||
// Calculates an Ethereum ECDSA signature for:
|
// Calculates an Ethereum ECDSA signature for:
|
||||||
// hash = keccak256("\x19${byteVersion}Ethereum Signed Message:\n${message length}${message}")
|
// hash = keccak256("\x19${byteVersion}Ethereum Signed Message:\n${message length}${message}")
|
||||||
|
|
@ -202,7 +200,6 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, addr common.M
|
||||||
}
|
}
|
||||||
sighash, msg := SignTextPlain(plainData)
|
sighash, msg := SignTextPlain(plainData)
|
||||||
req = &SignDataRequest{Rawdata: plainData, Message: msg, Hash: sighash, ContentType: mediaType}
|
req = &SignDataRequest{Rawdata: plainData, Message: msg, Hash: sighash, ContentType: mediaType}
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("content type '%s' not implemented for signing", contentType)
|
return nil, fmt.Errorf("content type '%s' not implemented for signing", contentType)
|
||||||
}
|
}
|
||||||
|
|
@ -382,7 +379,6 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
|
||||||
bytesValue = append(bytesValue, _byte)
|
bytesValue = append(bytesValue, _byte)
|
||||||
}
|
}
|
||||||
primitiveEncValue = bytesValue
|
primitiveEncValue = bytesValue
|
||||||
break
|
|
||||||
case "bool":
|
case "bool":
|
||||||
primitiveEncType = "uint256"
|
primitiveEncType = "uint256"
|
||||||
var int64Val int64
|
var int64Val int64
|
||||||
|
|
@ -390,11 +386,9 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
|
||||||
int64Val = 1
|
int64Val = 1
|
||||||
}
|
}
|
||||||
primitiveEncValue = abi.U256(big.NewInt(int64Val))
|
primitiveEncValue = abi.U256(big.NewInt(int64Val))
|
||||||
break
|
|
||||||
case "bytes", "string":
|
case "bytes", "string":
|
||||||
primitiveEncType = "bytes32"
|
primitiveEncType = "bytes32"
|
||||||
primitiveEncValue = crypto.Keccak256(bytesValueOf(encValue))
|
primitiveEncValue = crypto.Keccak256(bytesValueOf(encValue))
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(encType, "bytes") {
|
if strings.HasPrefix(encType, "bytes") {
|
||||||
encTypes = append(encTypes, "bytes32")
|
encTypes = append(encTypes, "bytes32")
|
||||||
|
|
@ -404,15 +398,12 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
|
||||||
for i := 0; i < 32-size; i++ {
|
for i := 0; i < 32-size; i++ {
|
||||||
bytesValue = append(bytesValue, 0)
|
bytesValue = append(bytesValue, 0)
|
||||||
}
|
}
|
||||||
for _, _byte := range encValue.(hexutil.Bytes) {
|
bytesValue = append(bytesValue, encValue.(hexutil.Bytes)...)
|
||||||
bytesValue = append(bytesValue, _byte)
|
|
||||||
}
|
|
||||||
primitiveEncValue = bytesValue
|
primitiveEncValue = bytesValue
|
||||||
} else if strings.HasPrefix(encType, "uint") || strings.HasPrefix(encType, "int") {
|
} else if strings.HasPrefix(encType, "uint") || strings.HasPrefix(encType, "int") {
|
||||||
primitiveEncType = "uint256"
|
primitiveEncType = "uint256"
|
||||||
primitiveEncValue = abi.U256(encValue.(*big.Int))
|
primitiveEncValue = abi.U256(encValue.(*big.Int))
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
return primitiveEncType, primitiveEncValue
|
return primitiveEncType, primitiveEncValue
|
||||||
}
|
}
|
||||||
|
|
@ -600,11 +591,7 @@ func isStandardTypeStr(encType string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference types
|
// Reference types
|
||||||
if encType[len(encType)-1] == ']' {
|
return encType[len(encType)-1] == ']'
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid checks if the given domain is valid, i.e. contains at least
|
// IsValid checks if the given domain is valid, i.e. contains at least
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue