You can be interested in this document if:
- You want to create your own implementation of the request protocol
- You are curious enough to dive and see what is under the hood of the request protocol
You don't need to read this document if:
- You want to develop an app using the request protocol (see the API library instead here)
- Request logic Specification v2.0.0
- Content table
- Request
- Get a request from a list of actions
- Types
- Identity, Role and Signature
- Note on Version and Backward compatibility
- Example of a request state actions after actions
A request is the JSON object whichproperties
returned from a list of actions
that satisfies the following formats:
Property | Type | Description |
---|---|---|
requestId | string | ID as unique as possible |
creator | Identity | Identity of the creator of the request |
payee | Identity | Identity of the payee |
payer | Identity | Identity of the payer |
expectedAmount | Amount | Amount expected to be paid |
currency | String | Currency of the expected amount |
state | Enum('created', 'accepted', 'canceled') | State of the request |
events | Array | List of the actions performed |
extensionsData | Array | List of data used by the above layer |
version | String | Specification version by the request (2.0.0' here) |
timestamp | Number | - Timestamp of the request creation in seconds - this timestamp is given by the creator. It is not trustless. - This timestamp is also used to differentiate between identical requests |
nonce | Number | Number to differentiate several identical requests with the same timestamp |
Example
{
"creator":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"currency":"ETH",
"events":[
{
"name":"create",
"parameters":{
"expectedAmount":"123400000000000000",
"extensionsDataAddedLength":1,
"isSignedRequest":false
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
],
"expectedAmount":"123400000000000000",
"extensionsData":[
{
"id":"extension1",
"value":"whatever1"
}
],
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"payer":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"requestId":"0x1c2610cbc5bee43b6bc9800e69ec832fb7d50ea098a88877a0afdcac5981d3f8",
"state":"created",
"timestamp": 1545224094,
"version":"2.0.0"
}
An action is a JSON object created to modify the properties of a request.
An action is performed on a request
under conditions specified in the action itself.
An action is ignored if there exists a previous identical action. If their normalized hashes (see How to sign a JSON object) are identical the second action is ignored.
This mechanism counters a replay attack where one can replay an action already signed (e.g.: reduceExpectedAmount).
If one wants to create two similar actions, he must add an arbitrary number (see nonce later in this document).
IMPORTANT :
- The
actions
of arequest
are ordered (it means that only oneaction
modify a request at a time) - An
action
which does not satisfy its condition will be simply ignored
Property | Type | Description |
---|---|---|
name | Enum() | Name of the action to perform (see list of possible actions) |
parameters | Object | Parameters of the actions |
signature | Signature | Signature of the object { name, parameters, version } |
Name | Description | Role Authorized |
---|---|---|
create | create a request | payee, payer |
accept | accept a request | payer |
cancel | cancel a request | payee, payer |
reduceExpectedAmount | reduce the expected amount | payee |
increaseExpectedAmount | increase the expected amount | payer |
addExtensionsData | add data for the extensions | payee, payer, third-party |
Type | Description | Requirement | |
---|---|---|---|
version | String | specification version | Mandatory |
expectedAmount | Amount | amount expected to be paid | Mandatory |
currency | String | Currency of the expected amount | Mandatory |
timestamp | Number | - Timestamp of the request creation in seconds - this timestamp is given by the creator. It is not trustless. - This timestamp is also used to differentiate between identical requests |
Mandatory |
payee | Identity | identity of the payee | Optional if payer given |
payer | Identity | identity of the payer | Optional if payee given |
extensionsData | Array | list of data used by the above layer | Optional |
nonce | Number | Number to differentiate several identical requests with the same timestamp - should be incremented by one for every new identical request |
Optional |
This action is valid, if:
- the Role of the action signer is payee or payer
A request created with the following properties:
Property | Value |
---|---|
requestId | Hash of this action |
creator | Identity of the signer |
payee | payee from parameters if exists, undefined otherwise |
payee | payer from parameters if exists, undefined otherwise |
expectedAmount | expectedAmount from parameters |
currency | currency from parameters |
state | created if signer is payee, accepted if signer is payer |
version | versions of Request protocol for which the request has been created |
extensionsData | extensionsData from parameters if exists, [] otherwise |
events | Array with one 'create' event (see below) |
the 'create' event:
Property | Value |
---|---|
name | 'create' |
parameters | Object |
parameters.isSignedRequest | false |
parameters.ExpectedAmount | expectedAmount from parameters |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of creation action:
{
"name":"create",
"parameters":{
"currency":"ETH",
"expectedAmount":"123400000000000000",
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"timestamp": 1545224094,
},
"version":"2.0.0",
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'create' event:
{
"name":"create",
"parameters":{
"expectedAmount":"123400000000000000",
"extensionsLength":0,
"isSignedRequest":false
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
Type | Description | Requirement | |
---|---|---|---|
requestId | String | ID of the request | Mandatory |
extensionsData | Array | list of data used by the above layer | Optional |
This action is valid, if:
- the request has a payer
- the Role of the action signer is the payer
- the request state is
created
Modify the following properties of the request:
Property | Value |
---|---|
state | accepted |
extensionsData | concat the extensionsData from parameters at its end |
events | add an 'accept' event (see below) at its end |
the 'accept' event:
Property | Value |
---|---|
name | 'accept' |
parameters | Object |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of action creation:
{
"name":"accept",
"parameters":{
"requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
},
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'accept' event:
{
"name":"accept",
"parameters":{
"extensionsLength":0,
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
Type | Description | Requirement | |
---|---|---|---|
requestId | String | ID of the request | Mandatory |
extensionsData | Array | list of data used by the above layer | Optional |
This action is valid, if:
-
the request has a payer
-
the Role of the action signer is the payer
-
the request state is
created
Or, if:
-
the request has a payee
-
the Role of the action signer is the payee
-
the request state is NOT
canceled
Modify the following properties of the request:
Property | Value |
---|---|
state | canceled |
extensionsData | concat the extensionsData from parameters at its end |
events | add an 'cancel' event (see below) at its end |
the 'cancel' event:
Property | Value |
---|---|
name | 'cancel' |
parameters | Object |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of cancel action:
{
"name":"cancel",
"parameters":{
"requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
},
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'cancel' event:
{
"name":"cancel",
"parameters":{
"extensionsLength":0,
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
Type | Description | Requirement | |
---|---|---|---|
requestId | String | ID of the request | Mandatory |
deltaAmount | Amount | amount to reduce to the expectedAmount | Mandatory |
extensionsData | Array | list of data used by the above layer | Optional |
nonce | Number | Number to differentiate identical actions | Optional |
This action is valid, if:
- the request has a payee
- the Role of the action signer is the payee
- the request state is NOT
canceled
- the deltaAmount is smaller or equal to expectedAmount
Modify the following properties of the request:
Property | Value |
---|---|
expectedAmount | expectedAmount minus deltaAmount from parameters |
extensionsData | concat the extensionsData from parameters at its end |
events | add an 'reduceExpectedAmount' event (see below) at its end |
the 'reduceExpectedAmount' event:
Property | Value |
---|---|
name | 'reduceExpectedAmount' |
parameters | Object |
parameters.deltaAmount | deltaAmount from parameters |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of reduceExpectedAmount action:
{
"name":"reduceExpectedAmount",
"parameters":{
"requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
"deltaAmount": "10000000",
},
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'reduceExpectedAmount' event:
{
"name":"reduceExpectedAmount",
"parameters":{
"deltaAmount": "10000000",
"extensionsLength":0,
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
Type | Description | Requirement | |
---|---|---|---|
requestId | String | ID of the request | Mandatory |
deltaAmount | Amount | amount to add to the expectedAmount | Mandatory |
extensionsData | Array | list of data used by the above layer | Optional |
nonce | Number | Number to differentiate identical actions | Optional |
This action is valid, if:
- the request has a payer
- the Role of the action signer is the payer
- the request state is NOT
canceled
Modify the following properties of the request:
Property | Value |
---|---|
expectedAmount | expectedAmount plus deltaAmount from parameters |
extensionsData | concat the extensionsData from parameters at its end |
events | add an 'increaseExpectedAmount' event (see below) at its end |
the 'increaseExpectedAmount' event:
Property | Value |
---|---|
name | 'increaseExpectedAmount' |
parameters | Object |
parameters.deltaAmount | deltaAmount from parameters |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of increaseExpectedAmount action:
{
"name":"increaseExpectedAmount",
"parameters":{
"requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
"deltaAmount": "10000000",
},
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'increaseExpectedAmount' event:
{
"name":"increaseExpectedAmount",
"parameters":{
"deltaAmount": "10000000",
"extensionsLength":0,
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
Type | Description | Requirement | |
---|---|---|---|
requestId | String | ID of the request | Mandatory |
extensionsData | Array | list of data used by the above layer | Mandatory |
nonce | Number | Number to differentiate identical actions | Optional |
None.
Modify the following properties of the request:
Property | Value |
---|---|
extensionsData | concatenate with the extensionsData from parameters |
events | add an 'addExtensionsData' event (see below) at its end |
the 'addExtensionsData' event:
Property | Value |
---|---|
name | 'addExtensionsData' |
parameters | Object |
parameters.extensionsDataAddedLength | length of the extensionsData from parameters |
actionSigner | Identity of the signer |
Example of addExtensionsData action:
{
"name":"addExtensionsData",
"parameters":{
"requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
"extensionsData": [{
"id": "pn_btc_address_based",
"action": "addPaymentAddress",
"parameters": {
"refundAddress": "2NEH4zBsz3za2hzjyjXsGETz4SpHzhjiSiG"
}
}]
},
"signature":{
"method":"ecdsa",
"value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}
Example of 'addExtensionsData' event:
{
"name":"addExtensionsData",
"parameters":{
"extensionsLength":1,
},
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
As mentioned above a request
is an JSON object with properties
modified by actions
.
From another perspective, you can get the properties
of a request
by interpreting a list of actions
.
(see Identity, Role and Signature)
(see Identity, Role and Signature)
To have a standard format for number that avoid limitation of size number in some languages, a valid amount is a string
representing a positive integer
in base 10.
Examples:
"11235813213455891442333776109871597258441816765" // OK
"0" // OK
0 // not valid
11235813213455891442333776109871597258441816765 // not valid
"-1123" // not valid
"3.14159" // not valid
"NaN" // not valid
"thirteen" // not valid
"0x12324094" // not valid
Note: Decimal number are not allowed for amount. But, each currency will be defined with a number of decimal (e.g.: 2 for USD, 18 for ETH, 8 for BTC )
Examples:
"12345667890123456789"
// could mean:
// 123456678901234567.89 USD
// 123456678901.23456789 BTC
// 12.345667890123456789 ETH
To manage low level identity in the request logic we use three different types of objects:
Identity
: a public piece of information an actor uses to identify themself (e.g.: the address in ethereum)Signature
: a proof of acknowledgment from anIdentity
SignatureParameters
: the parameters needed for anIdentity
to create aSignature
(e.g.: the privatekey in ethereum) And two methods:sign()
: generate aSignature
for data fromSignatureParameters
recover()
: get theIdentity
from data and itsSignature
+----------------+
+---------------------+ | Signed data |
|/SignatureParameters/| | |
+-----------+---------+ | +--------+ |
| | | Data | |
+--------+ Sign() | | +--------+ | Recover() +----------+
| Data +------------------------------->+ +------------------->+/Identity/|
+--------+ | +-----------+ | +----------+
| |/Signature/| |
| +-----------+ |
+----------------+
this is a json object with two properties:
type
: the type of identity (e.g.: 'ethereumAddress' for an ethereum identity like)value
: the actual value to recognize the identity (e.g.: for 'ethereumAddress' type, it would be something like '0x742d35cc6634c0532925a3b844bc454e4438f44e')
Note: Two identities are equal if and only if their type
and value
are equal
Example
{
"type": "ethereumAddress",
"value": "0x742d35cc6634c0532925a3b844bc454e4438f44e"
}
Any Identity
have one and only one Role
in each request:
Role | conditions |
---|---|
payee | the identity is equal to the request payee |
payer | the identity is equal to the request payer |
thirdparty | every other condition listed above are NOT satisfied |
this is a json object with two properties:
method
: the method to sign (e.g.: 'ecdsa' for an Elliptic Curve Signature)value
: the signature itself
Note: Two signatures are equal if and only if their method
and value
are equal
Example
{
"method": "ecdsa",
"value": "0xe649fdfe25c3ee33061a8159be9b941141121c5bed8d07664cb67b7912819b4539841a206636c190178ac58978926dad1fe3637a10b656705b71bda5e187510c1b"
}
this is a json object with two properties:
method
: the method to sign (e.g.: 'ecdsa' for an Elliptic Curve Signature)privateKey
: the private key to sign with
Example
{
"method": "ecdsa",
"privateKey": "0x3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266"
}
List of the Signature methods supported in this version:
Method | Signature Value | SignatureParameter privateKey | Identity Type from recover() | Comment |
---|---|---|---|---|
ecdsa | hexadecimal string (e.g.: "0xe649f..") | hexadecimal string (e.g.: "0xe649f..") | EthereumAddress (see "Identity types supported" below) | |
ecdsa-ethereum | hexadecimal string (e.g.: "0xe649f..") | hexadecimal string (e.g.: "0xe649f..") | EthereumAddress (see "Identity types supported" below) | Similar to ecdsa but the signature is made with the Ethereum padding keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)) . Used for signing with the web3 tools (like Metamask). |
List of the Identity types supported in this version:
Type | Identity Value | Signature Method |
---|---|---|
ethereumAddress | hexadecimal string (e.g.: "0xe649f..") | ecdsa (see "Signature methods supported" above) |
The signature of an JSON object is made on the keccak256
hash of the object:
- with its properties deeply alphabetically sorted
- stringified
- lowerCased
The versions of the Request logic specifications follow the semver 2.0.0. Every request is create with one and only one version of the specification.
By default, an implementation of the specifications will be able to handle only the requests following the specification versions with:
- The same
major
version - A
minor
version equal or inferior
Some exceptions will be done for versions that need to be blacklisted (e.g.: versions with vulnerabilities)
Bob wants to request 0.12 BTC to Alice.
Bob has his private Signature parameters
from which it can generate his Identity
:
{
"signatureParams": {
"method": "ecdsa",
"privateKey": "0x04674d2e53e0e14653487d7323cc5f0a7959c83067f5654cafe4094bde90fa8a",
},
"identity": {
"type": "ethereumAddress",
"value": "0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce",
}
}
Alice has his own Signature parameters
and Identity
:
{
"signatureParams": {
"method": "ecdsa",
"privateKey": "0x0906ff14227cead2b25811514302d57706e7d5013fcc40eca5985b216baeb998",
},
"identity": {
"type": "ethereumAddress",
"value": "0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6",
}
}
- Bob creates a request of 0.1234 ETH to Alice
- Bob makes a discount of 0.1 ETH
- Alice accept the request
We now follow the state
of the request after each actions
:
The action to create the request from Bob to Alice from Bob (signed by Bob):
{
"data":{
"name":"create",
"parameters":{
"currency":"ETH",
"expectedAmount":"123400000000000000",
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"payer":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"timestamp":1544426030
},
"version":"2.0.0"
},
"signature":{
"method":"ecdsa",
"value":"0xac9e9e43381d882f3edc506277b8ad74ca3fc0ed2184663b65ccbab921df114807d7e68fd03b668afffee1feb977c9082657f1a05f57c0b1f92e9b46ca22dfc31c"
}
}
The request state after interpreting the action above:
{
"currency":"ETH",
"expectedAmount":"123400000000000000",
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"payer":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"timestamp":1544426030,
"requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
"version":"2.0.0",
"events":[
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"name":"create",
"parameters":{
"expectedAmount":"123400000000000000",
"extensionsDataLength":0,
"isSignedRequest":false
}
}
],
"state":"created",
"creator":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
The action to make a discount (signed by Bob);
{
"data":{
"name":"reduceExpectedAmount",
"parameters":{
"deltaAmount":"100000000000000000",
"requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905"
},
"version":"2.0.0"
},
"signature":{
"method":"ecdsa",
"value":"0x649c5fdd54e781dfb480f9b01cc9ac8cd9d7630e2dd3b9a8443865ee00d5015805e6b3bbce9be35ef124e92afba80db79d913cdc756fe4e911f3413ae6a24b971b"
}
}
The request state after interpreting the new action with the previous state:
{
"currency":"ETH",
"expectedAmount":"23400000000000000",
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"payer":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"timestamp":1544426030,
"requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
"version":"2.0.0",
"events":[
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"name":"create",
"parameters":{
"expectedAmount":"123400000000000000",
"extensionsDataLength":0,
"isSignedRequest":false
}
},
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"name":"reduceExpectedAmount",
"parameters":{
"deltaAmount":"100000000000000000",
"extensionsDataLength":0
}
}
],
"state":"created",
"creator":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}
The action to accept the request (signed by Alice):
{
"data":{
"name":"accept",
"parameters":{
"requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905"
},
"version":"2.0.0"
},
"signature":{
"method":"ecdsa",
"value":"0xf94380c553c90810deb5625571649759f8591bf923f5773e436fec322d01752d676a6f822dee2c2097f4bb70b16273b4826e6026f9f98a31cfafab8f1bdda2eb1b"
}
}
The request state after interpreting the new action with the previous state:
{
"currency":"ETH",
"expectedAmount":"23400000000000000",
"payee":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"payer":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"timestamp":1544426030,
"requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
"version":"2.0.0",
"events":[
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"name":"create",
"parameters":{
"expectedAmount":"123400000000000000",
"extensionsDataLength":0,
"isSignedRequest":false
}
},
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
},
"name":"reduceExpectedAmount",
"parameters":{
"deltaAmount":"100000000000000000",
"extensionsDataLength":0
}
},
{
"actionSigner":{
"type":"ethereumAddress",
"value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
},
"name":"accept",
"parameters":{
"extensionsDataLength":0
}
}
],
"state":"accepted",
"creator":{
"type":"ethereumAddress",
"value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
}
}