2018-05-15 18:31:44 +00:00
|
|
|
---
|
|
|
|
eip: 1066
|
|
|
|
title: Status Codes
|
|
|
|
author: Brooklyn Zelenka (@expede), Tom Carchrae (@carchrae), Gleb Naumenko (@naumenkogs)
|
|
|
|
discussions-to: https://ethereum-magicians.org/t/erc-1066-ethereum-status-codes-esc/
|
|
|
|
status: Draft
|
|
|
|
type: Standards Track
|
|
|
|
category: ERC
|
|
|
|
created: 2018-05-05
|
|
|
|
---
|
|
|
|
|
|
|
|
## Simple Summary
|
|
|
|
|
|
|
|
Broadly applicable status codes for Ethereum smart contracts.
|
|
|
|
|
|
|
|
## Abstract
|
|
|
|
|
|
|
|
This standard outlines a common set of Ethereum status codes (ESC) in the same
|
|
|
|
vein as HTTP statuses. This provides a shared set of signals to allow smart contracts
|
|
|
|
to react to situations autonomously, expose localized error messages to users, and so on.
|
|
|
|
|
|
|
|
The current state of the art is to either `revert` and require human intervention,
|
|
|
|
or return a Boolean pass/fail status. Status codes are similar-but-orthogonal
|
|
|
|
to `revert`ing with a reason, but aimed at automation and translation.
|
|
|
|
|
|
|
|
As is the case with HTTP, having a standard set of known codes has many benefits for developers.
|
|
|
|
They remove friction from needing to develop your own schemes for every contract,
|
|
|
|
makes inter-contract automation easier, and makes it easier to broadly understand
|
|
|
|
which of the finite states your request produced. Importantly, it makes it much easier
|
|
|
|
to distinguish between expected errors states, and truly exceptional conditions
|
|
|
|
that require halting execution.
|
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
|
|
|
### Autonomy
|
|
|
|
|
|
|
|
Smart contracts are largely intended to be autonomous. While each contract may
|
|
|
|
define a specific interface, having a common set of semantic codes can help
|
|
|
|
developers write code that can react appropriately to various situations.
|
|
|
|
|
|
|
|
### Semantic Density
|
|
|
|
|
|
|
|
HTTP status codes are widely used for this purpose. BEAM languages use atoms
|
|
|
|
and tagged tuples to signify much the same information. Both provide a lot of
|
|
|
|
information both to the programmer (debugging for instance), and to the program
|
|
|
|
that needs to decide what to do next.
|
|
|
|
|
|
|
|
ESCs convey a much richer set of information than Booleans,
|
|
|
|
and are able to be reacted to autonomously unlike arbitrary strings.
|
|
|
|
|
|
|
|
### User Feedback
|
|
|
|
|
|
|
|
Since status codes are finite and known in advance, we can provide global,
|
|
|
|
human-readable sets of status messages. These may also be translated into any language,
|
|
|
|
differing levels of technical detail, added as `revert` messages, natspecs, and so on.
|
|
|
|
|
|
|
|
We also see a desire for this [in transactions](http://eips.ethereum.org/EIPS/eip-658),
|
|
|
|
and there's no reason that ESCs couldn't be used by the EVM itself.
|
|
|
|
|
|
|
|
### More than Pass/Fail
|
|
|
|
|
|
|
|
While clearly related, status codes are complementary to "revert with reason".
|
|
|
|
ESCs are not limited to rolling back the transaction, and may represent known error states
|
|
|
|
without halting execution. They may also represent off-chain conditions,
|
|
|
|
supply a string to revert, signal time delays, and more.
|
|
|
|
|
|
|
|
## Specification
|
|
|
|
|
|
|
|
### Format
|
|
|
|
|
|
|
|
Codes are returned as the first value of potentially multiple return values.
|
|
|
|
|
|
|
|
```solidity
|
|
|
|
// Status only
|
|
|
|
|
|
|
|
function isInt(uint num) public pure returns (byte status) {
|
|
|
|
return hex"01";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Status and value
|
|
|
|
|
|
|
|
uint8 private counter;
|
|
|
|
|
|
|
|
function safeIncrement(uint8 interval) public returns (byte status, uint8 newCounter) {
|
|
|
|
uint8 updated = counter + interval;
|
|
|
|
|
|
|
|
if (updated >= counter) {
|
|
|
|
counter = updated;
|
|
|
|
return (hex"01", updated);
|
|
|
|
} else {
|
|
|
|
return (hex"00", counter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2018-06-08 02:34:47 +00:00
|
|
|
In the rare case that there are multiple codes required to express an idea,
|
|
|
|
they should be organized in ascending order.
|
2018-05-15 18:31:44 +00:00
|
|
|
|
|
|
|
### Code Table
|
|
|
|
|
|
|
|
Codes break nicely into a 16x16 matrix, represented as a 2-digit hex number.
|
|
|
|
The high nibble represents the code's kind or "category", and the low nibble contains
|
|
|
|
the state or "reason". We present them below as separate tables per range for
|
2018-06-08 02:34:47 +00:00
|
|
|
explanatory and layout reasons.
|
2018-05-15 18:31:44 +00:00
|
|
|
|
|
|
|
Unspecified codes are _not_ free for arbitrary use, but rather open for further specification.
|
|
|
|
|
|
|
|
#### Generic
|
|
|
|
|
|
|
|
General codes. These double as bare "reasons", since `0x01 == 1`.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:------------------------|
|
|
|
|
| `0x00` | Failure |
|
|
|
|
| `0x01` | Success |
|
|
|
|
| `0x02` | Accepted / Started |
|
|
|
|
| `0x03` | Awaiting / Before |
|
|
|
|
| `0x04` | Action Required |
|
|
|
|
| `0x05` | Expired |
|
|
|
|
| `0x06` | |
|
|
|
|
| `0x07` | |
|
|
|
|
| `0x08` | |
|
|
|
|
| `0x09` | |
|
|
|
|
| `0x0A` | |
|
|
|
|
| `0x0B` | |
|
|
|
|
| `0x0C` | |
|
|
|
|
| `0x0D` | |
|
|
|
|
| `0x0E` | |
|
|
|
|
| `0x0F` | Meta or Info Only |
|
|
|
|
|
|
|
|
#### Permission
|
|
|
|
|
|
|
|
Related to permisson, authorization, approval, and so on.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:-------------------------|
|
|
|
|
| `0x10` | Disallowed |
|
|
|
|
| `0x11` | Allowed |
|
|
|
|
| `0x12` | Requested Permission |
|
|
|
|
| `0x13` | Awaiting Permission |
|
|
|
|
| `0x14` | Awaiting Your Permission |
|
|
|
|
| `0x15` | No Longer Allowed |
|
|
|
|
| `0x16` | |
|
|
|
|
| `0x17` | |
|
|
|
|
| `0x18` | |
|
|
|
|
| `0x19` | |
|
|
|
|
| `0x1A` | |
|
|
|
|
| `0x1B` | |
|
|
|
|
| `0x1C` | |
|
|
|
|
| `0x1D` | |
|
|
|
|
| `0x1E` | |
|
|
|
|
| `0x1F` | Permission Meta or Info |
|
|
|
|
|
|
|
|
#### Find, Match, &c
|
|
|
|
|
|
|
|
This range is broadly intended for finding and matching.
|
|
|
|
Data lookups and order matching are two common use cases.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:-------------------------|
|
|
|
|
| `0x20` | Not Found |
|
|
|
|
| `0x21` | Found |
|
|
|
|
| `0x22` | Match Request Sent |
|
|
|
|
| `0x23` | Awaiting Match |
|
|
|
|
| `0x24` | Match Request Received |
|
|
|
|
| `0x25` | Out of Range |
|
|
|
|
| `0x26` | |
|
|
|
|
| `0x27` | |
|
|
|
|
| `0x28` | |
|
|
|
|
| `0x29` | |
|
|
|
|
| `0x2A` | |
|
|
|
|
| `0x2B` | |
|
|
|
|
| `0x2C` | |
|
|
|
|
| `0x2D` | |
|
|
|
|
| `0x2E` | |
|
|
|
|
| `0x2F` | Matching Meta or Info |
|
|
|
|
|
|
|
|
#### Negotiation, Terms, and Offers
|
|
|
|
|
|
|
|
Negotiation, and very broadly the flow of such transactions.
|
2018-06-08 02:34:47 +00:00
|
|
|
Note that "other party" may be more than one actor (not necessarily the sender).
|
2018-05-15 18:31:44 +00:00
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:----------------------------|
|
|
|
|
| `0x30` | Other Party Disagreed |
|
|
|
|
| `0x31` | Other Party Agreed |
|
|
|
|
| `0x32` | Sent Offer |
|
|
|
|
| `0x33` | Awaiting Their Ratification |
|
|
|
|
| `0x34` | Awaiting Your Ratification |
|
|
|
|
| `0x35` | Offer Expired |
|
|
|
|
| `0x36` | |
|
|
|
|
| `0x37` | |
|
|
|
|
| `0x38` | |
|
|
|
|
| `0x39` | |
|
|
|
|
| `0x3A` | |
|
|
|
|
| `0x3B` | |
|
|
|
|
| `0x3C` | |
|
|
|
|
| `0x3D` | |
|
|
|
|
| `0x3E` | |
|
|
|
|
| `0x3F` | Negotiation Meta or Info |
|
|
|
|
|
|
|
|
#### Availability
|
|
|
|
|
|
|
|
Service or action availability.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:----------------------------|
|
|
|
|
| `0x40` | Unavailable |
|
|
|
|
| `0x41` | Available |
|
|
|
|
| `0x42` | You May Begin |
|
|
|
|
| `0x43` | Not Yet Available |
|
|
|
|
| `0x44` | Awaiting Your Availability |
|
|
|
|
| `0x45` | No Longer Available |
|
|
|
|
| `0x46` | |
|
|
|
|
| `0x47` | |
|
|
|
|
| `0x48` | |
|
|
|
|
| `0x49` | |
|
|
|
|
| `0x4A` | |
|
|
|
|
| `0x4B` | |
|
|
|
|
| `0x4C` | |
|
|
|
|
| `0x4D` | |
|
|
|
|
| `0x4E` | |
|
|
|
|
| `0x4F` | Availability Meta or Info |
|
|
|
|
|
|
|
|
#### `0x5_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0x6_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0x7_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0x8_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0x9_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### Application-Specific Codes
|
|
|
|
|
|
|
|
Contracts may have special states that they need to signal.
|
|
|
|
This proposal only outlines the broadest meanings, but implementers may have very
|
|
|
|
specific meanings for each, as long as they are coherent with the broader definition.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:--------------------------------|
|
|
|
|
| `0xA0` | App-Specific Failure |
|
|
|
|
| `0xA1` | App-Specific Success |
|
|
|
|
| `0xA2` | App-Specific Acceptance / Start |
|
|
|
|
| `0xA3` | App-Specific Awaiting / Before |
|
|
|
|
| `0xA4` | App-Specific Action Required |
|
|
|
|
| `0xA5` | App-Specific Expiry |
|
|
|
|
| `0xA6` | |
|
|
|
|
| `0xA7` | |
|
|
|
|
| `0xA8` | |
|
|
|
|
| `0xA9` | |
|
|
|
|
| `0xAA` | |
|
|
|
|
| `0xAB` | |
|
|
|
|
| `0xAC` | |
|
|
|
|
| `0xAD` | |
|
|
|
|
| `0xAE` | |
|
|
|
|
| `0xAF` | App-Specific Meta or Info |
|
|
|
|
|
|
|
|
#### `0xB_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0xC_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### `0xD_` TBD
|
|
|
|
|
|
|
|
Currently unspecified
|
|
|
|
|
|
|
|
#### Cryptography and Authentication
|
|
|
|
|
|
|
|
Actions around signatures, cryptography, signing, and application-level authentication.
|
|
|
|
|
|
|
|
The meta code `0xEF` is often used to signal a payload descibing the algorithm
|
|
|
|
or process used.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:----------------------------|
|
|
|
|
| `0xE0` | Decrypt Failure |
|
|
|
|
| `0xE1` | Decrypt Success |
|
|
|
|
| `0xE2` | Signed |
|
|
|
|
| `0xE3` | Their Signature Required |
|
|
|
|
| `0xE4` | Your Signature Required |
|
|
|
|
| `0xE5` | Auth Expired |
|
|
|
|
| `0xE6` | |
|
|
|
|
| `0xE7` | |
|
|
|
|
| `0xE8` | |
|
|
|
|
| `0xE9` | |
|
|
|
|
| `0xEA` | |
|
|
|
|
| `0xEB` | |
|
|
|
|
| `0xEC` | |
|
|
|
|
| `0xED` | |
|
|
|
|
| `0xEE` | |
|
|
|
|
| `0xEF` | Crypto Info or Meta |
|
|
|
|
|
|
|
|
#### `0xF0` Off-Chain
|
|
|
|
|
|
|
|
For off-chain actions. Much like th `0x0_: Generic` range, `0xF_` is very general,
|
|
|
|
and does little to modify the reason.
|
|
|
|
|
|
|
|
Among other things, the meta code `0xFF` may be used to describe what the off-chain process is.
|
|
|
|
|
|
|
|
| Code | Description |
|
|
|
|
|-----------------|:------------------------------|
|
|
|
|
| `0xF0` | Off-Chain Failure |
|
|
|
|
| `0xF1` | Off-Chain Success |
|
|
|
|
| `0xF2` | Off-Chain Process Stared |
|
|
|
|
| `0xF3` | Awaiting Off-Chain Completion |
|
|
|
|
| `0xF4` | Off-Chain Action Required |
|
|
|
|
| `0xF5` | Off-Chain Service Unavailable |
|
|
|
|
| `0xF6` | |
|
|
|
|
| `0xF7` | |
|
|
|
|
| `0xF8` | |
|
|
|
|
| `0xF9` | |
|
|
|
|
| `0xFA` | |
|
|
|
|
| `0xFB` | |
|
|
|
|
| `0xFC` | |
|
|
|
|
| `0xFD` | |
|
|
|
|
| `0xFE` | |
|
|
|
|
| `0xFF` | Off-Chain Info or Meta |
|
|
|
|
|
|
|
|
### Example Function Change
|
|
|
|
|
|
|
|
```solidity
|
|
|
|
uint256 private startTime;
|
|
|
|
mapping(address => uint) private counters;
|
|
|
|
|
|
|
|
// Before
|
|
|
|
function increase() public returns (bool _available) {
|
|
|
|
if (now < startTime && counters[msg.sender] == 0) {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
counters[msg.sender] += 1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// After
|
|
|
|
function increase() public returns (byte _status) {
|
|
|
|
if (now < start) { return hex"43"; } // Not yet available
|
|
|
|
if (counters[msg.sender] == 0) { return hex"10"; } // Not authorized
|
|
|
|
|
|
|
|
counters[msg.sender] += 1;
|
|
|
|
return hex"01"; // Success
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Example Sequence Diagrams
|
|
|
|
|
|
|
|
```
|
|
|
|
0x03 = Waiting
|
|
|
|
0x31 = Other Party (ie: not you) Agreed
|
|
|
|
0x41 = Available
|
|
|
|
0x43 = Not Yet Available
|
|
|
|
|
|
|
|
|
|
|
|
Exchange
|
|
|
|
|
|
|
|
|
|
|
|
AwesomeCoin DEX TraderBot
|
|
|
|
+ + +
|
|
|
|
| | buy(AwesomeCoin) |
|
|
|
|
| | <------------------------+
|
|
|
|
| buy() | |
|
|
|
|
| <---------------------+ |
|
|
|
|
| | |
|
|
|
|
| Status [0x43] | |
|
|
|
|
+---------------------> | Status [0x43] |
|
|
|
|
| +------------------------> |
|
|
|
|
| | |
|
|
|
|
| | isDoneYet() |
|
|
|
|
| | <------------------------+
|
|
|
|
| | |
|
|
|
|
| | Status [0x43] |
|
|
|
|
| +------------------------> |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| Status [0x41] | |
|
|
|
|
+---------------------> | |
|
|
|
|
| | |
|
|
|
|
| buy() | |
|
|
|
|
| <---------------------+ |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| Status [0x31] | |
|
|
|
|
+---------------------> | Status [0x31] |
|
|
|
|
| +------------------------> |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
+ + +
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
0x01 = Generic Success
|
|
|
|
0x10 = Disallowed
|
|
|
|
0x11 = Allowed
|
|
|
|
|
|
|
|
Token Validation
|
|
|
|
|
|
|
|
|
|
|
|
Buyer RegulatedToken TokenValidator IDChecker SpendLimiter
|
|
|
|
+ + + + +
|
|
|
|
| buy() | | | |
|
|
|
|
+------------------------> | check() | | |
|
|
|
|
| +-----------------------> | check() | |
|
|
|
|
| | +-----------------------> | |
|
|
|
|
| | | | |
|
|
|
|
| | | Status [0x10] | |
|
|
|
|
| | Status [0x10] | <-----------------------+ |
|
|
|
|
| revert() | <-----------------------+ | |
|
|
|
|
| <------------------------+ | | |
|
|
|
|
| | | | |
|
|
|
|
+---------------------------+ | | | |
|
|
|
|
| | | | | |
|
|
|
|
| Updates ID with provider | | | | |
|
|
|
|
| | | | | |
|
|
|
|
+---------------------------+ | | | |
|
|
|
|
| | | | |
|
|
|
|
| buy() | | | |
|
|
|
|
+------------------------> | check() | | |
|
|
|
|
| +-----------------------> | check() | |
|
|
|
|
| | +-----------------------> | |
|
|
|
|
| | | | |
|
|
|
|
| | | Status [0x11] | |
|
|
|
|
| | | <-----------------------+ |
|
|
|
|
| | | | |
|
|
|
|
| | | | check() |
|
|
|
|
| | +-------------------------------------------> |
|
|
|
|
| | | | |
|
|
|
|
| | | | Status [0x11] |
|
|
|
|
| | Status [0x11] | <-------------------------------------------+
|
|
|
|
| Status [0x01] | <-----------------------+ | |
|
|
|
|
| <------------------------+ | | |
|
|
|
|
| | | | |
|
|
|
|
| | | | |
|
|
|
|
| | | | |
|
|
|
|
+ + + + +
|
|
|
|
```
|
|
|
|
|
|
|
|
## Rationale
|
|
|
|
|
|
|
|
### Encoding
|
|
|
|
|
|
|
|
ESCs are encoded as a `byte`. Hex values break nicely into high and low nibbles:
|
|
|
|
`category` and `reason`. For instance, `hex"01"` stands for general success
|
|
|
|
and `hex"00"` for general failure.
|
|
|
|
|
|
|
|
`byte` is quite lightweight, and can be easily packed with multiple codes into
|
|
|
|
a `bytes32` (or similar) if desired. It is also easily interoperable with `uint8`,
|
|
|
|
cast from `enum`s, and so on.
|
|
|
|
|
|
|
|
#### Alternatives
|
|
|
|
|
|
|
|
Alternate schemes include `bytes32` and `uint8`. While these work reasonably
|
|
|
|
well, they have drawbacks.
|
|
|
|
|
|
|
|
`uint8` feels even more similar to HTTP status codes, and enums don't require
|
|
|
|
as much casting. However does not break as evenly as a square table
|
|
|
|
(256 doesn't look as nice in base 10).
|
|
|
|
|
|
|
|
Packing multiple codes into a single `bytes32` is nice in theory, but poses additional
|
|
|
|
challenges. Unused space may be interpeted as `0x00 Failure`, you can only efficiently
|
|
|
|
pack four codes at once, and there is a challenge in ensuring that code combinations
|
|
|
|
are sensible. Forcing four codes into a packed representation encourages multiple
|
|
|
|
status codes to be returned, which is often more information than strictly nessesary.
|
|
|
|
This can lead to paradoxical results (ex `0x00` and `0x01` together),
|
|
|
|
or greater resorces allocated to interpreting 256<sup>4</sup> (4.3 billion) permutations.
|
|
|
|
|
|
|
|
### Multiple Returns
|
|
|
|
|
|
|
|
While there may be cases where packing a byte array of ESCs may make sense, the simplest,
|
|
|
|
most forwards-compatible method of transmission is as the first value of a multiple return.
|
|
|
|
|
|
|
|
Familiarity is also a motivating factor. A consistent position and encoding together
|
|
|
|
follow the principle of least surprise. It is both viewable as a "header" in the HTTP analogy,
|
|
|
|
or like the "tag" in BEAM tagged tupples.
|
|
|
|
|
|
|
|
### Human Readable
|
|
|
|
|
|
|
|
Developers should not be required to memorize 256 codes. However, they break nicely into a table.
|
|
|
|
Cognitive load is lowered by organizing the table into categories and reasons.
|
|
|
|
`0x10` and `0x11` belong to the same category, and `0x04` shares a reason with `0x24`
|
|
|
|
|
|
|
|
While this repository includes helper enums, we have found working directly in
|
|
|
|
the hex values to be quite natural. ESC `0x10` is just as comfortable as HTTP 401, for example.
|
|
|
|
|
|
|
|
### Extensiblilty
|
|
|
|
|
|
|
|
The `0xA` category is reserved for application-specific statuses.
|
|
|
|
In the case that 256 codes become insufficient, `bytes1` may be embedded in larger byte arrays.
|
|
|
|
|
|
|
|
### EVM Codes
|
|
|
|
|
|
|
|
The EVM also returns a status code in transactions; specifically `0x00` and `0x01`.
|
|
|
|
This proposal both matches the meanings of those two codes, and could later be used
|
|
|
|
at the EVM level.
|
|
|
|
|
|
|
|
### Empty Space
|
|
|
|
|
|
|
|
Much like how HTTP status codes have large unused ranges, there are totally empty
|
|
|
|
sections in this proposal. The intent is to not impose a complete set of codes up front,
|
|
|
|
and to allow users to suggest uses for these spaces as time progresses.
|
|
|
|
|
|
|
|
### Nibble Order
|
|
|
|
|
|
|
|
Nibble order makes no difference to the machine, and is purely mnemonic.
|
|
|
|
This design was originally in opposite order, but changed it for a few convenience factors.
|
|
|
|
Since it's a different scheme from HTTP, it may feel strange initially,
|
|
|
|
but becomes very natural after a couple hours of use.
|
|
|
|
|
|
|
|
#### Short Forms
|
|
|
|
|
|
|
|
Generic is `0x0_`, general codes are consistent with their integer representations
|
|
|
|
|
|
|
|
```solidity
|
|
|
|
hex"1" == hex"01" == 1 // with casting
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Contract Categories
|
|
|
|
|
|
|
|
Many applications will always be part of the same category.
|
|
|
|
For instance, validation will generally be in the `0x10` range.
|
|
|
|
|
|
|
|
```solidity
|
|
|
|
contract Whitelist {
|
|
|
|
mapping(address => bool) private whitelist;
|
|
|
|
uint256 private deadline;
|
|
|
|
byte constant private prefix = hex"10";
|
|
|
|
|
|
|
|
check(address _, address _user) returns (byte _status) {
|
|
|
|
if (now >= deadline) { return prefix | 5; }
|
|
|
|
if (whitelist[_user]) { return prefix | 1; }
|
|
|
|
return prefix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Helpers
|
|
|
|
|
|
|
|
This above also means that working with app-specific enums is slightly easier:
|
|
|
|
|
|
|
|
```solidity
|
|
|
|
enum Sleep {
|
|
|
|
Awake,
|
|
|
|
Asleep,
|
|
|
|
REM,
|
|
|
|
FallingAsleep
|
|
|
|
}
|
|
|
|
|
|
|
|
// From the helper library
|
|
|
|
|
|
|
|
function appCode(Sleep _state) returns (byte code) {
|
|
|
|
return byte(160 + _state); // 160 = 0xA0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Versus
|
|
|
|
|
|
|
|
function appCode(Sleep _state) returns (byte code) {
|
|
|
|
return byte((16 * _state) + 10); // 10 = 0xA
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Implementation
|
|
|
|
|
2018-07-14 15:53:40 +00:00
|
|
|
Reference cases and helper libraries (Solidity and JS) can be found at:
|
|
|
|
* [Source Code](https://github.com/expede/ethereum-status-codes/)
|
|
|
|
* [Package on npm](https://www.npmjs.com/package/ethereum-status-codes)
|
2018-05-15 18:31:44 +00:00
|
|
|
|
|
|
|
## Copyright
|
|
|
|
|
|
|
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|