eip712_enc/lib.rs
1// Copyright 2015-2019 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Ethereum is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
16
17//! EIP-712 encoding utilities
18//!
19//! # Specification
20//!
21//! `encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)`
22//! - data adheres to 𝕊, a structure defined in the rigorous eip-712
23//! - `\x01` is needed to comply with EIP-191
24//! - `domainSeparator` and `hashStruct` are defined below
25//!
26//! ## A) domainSeparator
27//!
28//! `domainSeparator = hashStruct(eip712Domain)`
29//! <br/>
30//! <br/>
31//! Struct named `EIP712Domain` with the following fields
32//!
33//! - `name: String`
34//! - `version: String`
35//! - `chain_id: U256`,
36//! - `verifying_contract: H160`
37//! - `salt: Option<H256>`
38//!
39//! ## C) hashStruct
40//!
41//! `hashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))`
42//! <br/>
43//! `typeHash = keccak256(encodeType(typeOf(s)))`
44//!
45//! ### i) encodeType
46//!
47//! - `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"`
48//! - each member is written as `type ‖ " " ‖ name`
49//! - encodings cascade down and are sorted by name
50//!
51//! ### ii) encodeData
52//!
53//! - `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`
54//! - each encoded member is 32-byte long
55//!
56//! #### a) atomic
57//!
58//! - `boolean` => `U256`
59//! - `address` => `H160`
60//! - `uint` => sign-extended `U256` in big endian order
61//! - `bytes1:31` => `H@256`
62//!
63//! #### b) dynamic
64//!
65//! - `bytes` => `keccak256(bytes)`
66//! - `string` => `keccak256(string)`
67//!
68//! #### c) referenced
69//!
70//! - `array` => `keccak256(encodeData(array))`
71//! - `struct` => `rec(keccak256(hashStruct(struct)))`
72//!
73//! ## D) Example
74//! ### Query
75//! ```json
76//! {
77//! "jsonrpc": "2.0",
78//! "method": "eth_signTypedData",
79//! "params": [
80//! "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
81//! {
82//! "types": {
83//! "EIP712Domain": [
84//! {
85//! "name": "name",
86//! "type": "string"
87//! },
88//! {
89//! "name": "version",
90//! "type": "string"
91//! },
92//! {
93//! "name": "chainId",
94//! "type": "uint256"
95//! },
96//! {
97//! "name": "verifyingContract",
98//! "type": "address"
99//! }
100//! ],
101//! "Person": [
102//! {
103//! "name": "name",
104//! "type": "string"
105//! },
106//! {
107//! "name": "wallet",
108//! "type": "address"
109//! }
110//! ],
111//! "Mail": [
112//! {
113//! "name": "from",
114//! "type": "Person"
115//! },
116//! {
117//! "name": "to",
118//! "type": "Person"
119//! },
120//! {
121//! "name": "contents",
122//! "type": "string"
123//! }
124//! ]
125//! },
126//! "primaryType": "Mail",
127//! "domain": {
128//! "name": "Ether Mail",
129//! "version": "1",
130//! "chainId": 1,
131//! "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
132//! },
133//! "message": {
134//! "from": {
135//! "name": "Cow",
136//! "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
137//! },
138//! "to": {
139//! "name": "Bob",
140//! "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
141//! },
142//! "contents": "Hello, Bob!"
143//! }
144//! }
145//! ],
146//! "id": 1
147//! }
148//! ```
149//
150//! ### Response
151//! ```json
152//! {
153//! "id":1,
154//! "jsonrpc": "2.0",
155//! "result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
156//! }
157//! ```
158
159#![warn(missing_docs)]
160
161#[macro_use]
162extern crate validator_derive;
163
164mod eip712;
165mod encode;
166mod error;
167mod parser;
168
169/// EIP712 struct
170pub use crate::eip712::EIP712;
171/// the EIP-712 encoding function
172pub use crate::encode::hash_structured_data;
173/// encoding Error types
174pub use crate::error::{Error, ErrorKind};