-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial contract spec. * Adding first language spec. * Fixing table. * Fixing bullet points. * Life cycle info and improved type descriptions. * Map definition. * ABI. * ABI alternatives. * Formatting. * Local calls. * Transactions. * AEVM. * Typos. * Fixing more typos. * Fixing copy paste errors. * Contracts ARE accounts. * Fix wording. * gas price. * Algorithm for contract address. * Amount and deposit in transaction and state. * Abstract contracts. * Omitted types. * Fees in call. * Fix form. * New extenal calling convention ABI. * Added some new VMs * Code fromatting * Renaming to Sophia. * Gas cost. * Spelling. * Starting to document contract API.
- Loading branch information
1 parent
ce2af06
commit 7983223
Showing
9 changed files
with
774 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
[back](./contracts.md) | ||
# Virtual Machines on the AEternity blockchain | ||
|
||
A smart contract is associated with a virtual machine for the execution of that | ||
contract. The AEternity blockchain supports four virtual machines. | ||
|
||
1. HLM - A high level machine for executing logical formulas and blockchain operations. | ||
2. FTWVM - A Functional Typed Warded Virtual Machine | ||
3. AEVM - A version of the Ethereum VM | ||
3. FAEVM - A fast version of the Ethereum VM | ||
|
||
# HLM | ||
|
||
The High Level Machine can execute Ethereum block chain operations (transactions) and logical tests on | ||
block chain variables in straight line code. A contract on HLM has a two local key->value stores, | ||
one containing numbers and one containing strings. | ||
|
||
The cost for executing a HLM contract is directly proportional to the size of CODE+STORE. | ||
That is the gas used is bytesize(CODE+STORE) before contract execution. | ||
|
||
This allows for blindingly fast and cheap contracts with a known cost to be executed on the AEternity chain. | ||
|
||
HLM statements are of the form: | ||
``` | ||
IF BoolExpr THEN Statement ELSE Statement | ||
IF BoolExpr THEN Statement | ||
TX(SpendTx, A, B, Amount) | ||
TX... | ||
put_number(StringExpr, Aexpr) | ||
put_string(StringExpr, StringExpr) | ||
BoolExpr: | ||
true | ||
false | ||
if BoolExpr then BoolExpr else BoolExpr | ||
BoolExpr or BoolExpr | ||
BoolExpr and BoolExpr | ||
( BoolExpr ) | ||
StringExpr EQOP StringExpr | ||
AExpr COP AExpr | ||
StringExpr: | ||
Oracle(ID) | ||
String | ||
get_string(StringExpr) | ||
EQOP | ||
== | ||
!= | ||
AExpr: | ||
Number | ||
if BoolExpr then AExpr else AExpr | ||
balance(Account) | ||
contractbalance | ||
callvalue | ||
get_number(StringExpr) | ||
AExpr AOP AExpr | ||
( AExpr ) | ||
AOP: | ||
+ | ||
- | ||
div | ||
* | ||
COP: | ||
> | ||
< | ||
>= | ||
<= | ||
EQOP | ||
``` | ||
|
||
A HLM contract has a caller and an owner (creator). | ||
|
||
TODO: | ||
* Describe in detail which transactions are in the language | ||
* Describe when a transactions is valid (Owner, Caller, balance etc) | ||
* Describe how Oracle results are decoded and compared | ||
* Describe how HLM contracts are encoded (bytecode) | ||
* Describe calling convention | ||
* Describe return values | ||
* Describe how the key value stores are encoded | ||
|
||
# FTWVM | ||
|
||
The Functional Typed Warded Virtual Machine is used to efficiently and safely execute contracts written in the Sophia language. | ||
|
||
The FTWVM machine is Warded. This means that all arithmetic operations are checked for overflow and underflow if applicable. | ||
The machine has a signed arbitrary large number type so for most operations there should be no overflow. | ||
|
||
The FTWVM machine is typed. Every instruction and every instruction argument has a type. All argument types are checked when | ||
a contract is called. All data is tagged with the types. | ||
|
||
The FTWVM machine is functional. The machine supports the execution of functional languages with tagged data, | ||
automatic memory management and garbage collection. | ||
|
||
The FTWVM is a virtual machine the instructions are on a higher level than pure memory references. | ||
|
||
[TODO: Full description of the FTWVM] | ||
|
||
|
||
## The AEternity Ethereum Virtual Machine AEVM | ||
|
||
The AEVM is a version of the EVM: https://github.com/ethereum/yellowpaper | ||
|
||
The AEVM is emulated inside the Ethereum node an no marshaling of arguments, code and data is necessary. | ||
This makes for fast upstart and faster execution of most smaller contracts. | ||
|
||
There are a few differences between the EVM and the AEVM. | ||
|
||
The SELFDESTRUCT instruction is not immediate, instead the contract is set in a disabled state where neither | ||
new contracts nor call transactions can call the contract directly. When all other contracts referring to | ||
a disabled contract are fully disabled the contract is disabled. | ||
|
||
[TODO: Describe these instructions.] | ||
|
||
There is a PUSH N instruction. | ||
|
||
AEVM also has some new instructions that will make it into the EVM at some point: | ||
|
||
``` | ||
JUMPTO jump_target | ||
JUMPIF jump_target | ||
BEGINSUB n_args, n_results | ||
JUMPSUB jump_target | ||
RETURNSUB | ||
SHL | ||
SHR | ||
SAR | ||
ROL | ||
``` | ||
|
||
|
||
## The Fast AEternity Virtual Machine FAEVM | ||
|
||
The FAEVM is also version of the EVM: https://github.com/ethereum/yellowpaper and it follows the AEVM exactly. | ||
|
||
The FAEVM compiles the contract code to native code on supported hardware. The code will then execute outside | ||
of the Ethereum node and all code, data and arguments need to be marshaled to call the native code. This makes | ||
for slower calls but faster execution for larger contracts. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[back](./contracts.md) | ||
## Contract life cycle examples | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[back](./contracts.md) | ||
## Contract state tree | ||
|
||
The contracts and their interactions reside in a contract state tree that | ||
is included in the root hash. The existence of a contract and the | ||
existence of calls can be proven. | ||
|
||
### Contract state tree objects | ||
|
||
The contract state tree contains objects: | ||
- The contract definition (code binary) | ||
- The contract store (data binary) | ||
- The contract log (data binary) | ||
- Active flag (Boolean) | ||
- List of refering contracts | ||
- Calls & Return data | ||
- Deposit (amount) | ||
- vm_version | ||
|
||
As well as normal account fields. | ||
|
||
#### The contract definition | ||
|
||
- Created by a contract create transaction. | ||
- Deleted when an inactive contract has no more referers. | ||
|
||
|
||
### Contract state tree update | ||
|
||
|
||
|
||
### Pruning of contracts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
[back](./contracts.md) | ||
## Contract Transactions | ||
|
||
Contract transactions are of four types: | ||
- Create | ||
- Attach | ||
- Call | ||
- Disable -- To be decided. | ||
|
||
A contract is also a normal account with a balance, | ||
and the normal spend transaction can be applied to the account. | ||
|
||
When a contract is createad or called, the miner checks that the | ||
creator/caller has gas*gas_price (*10^-18) aeons in the account. | ||
|
||
The execution of the call will use a certain amount of gas up to | ||
the maximum given, that amount is decduced from the caller's | ||
account and added to the miner's account. | ||
|
||
### Create Contract Transaction | ||
|
||
Anyone can create a new contract by submitting a create contract transaction. | ||
|
||
The transaction contains: | ||
- The address of the contract owner (the one signing and paying for the transaction) | ||
- Nonce of the owner/creator account. | ||
- The byte code of the contract | ||
- The VM to use | ||
- A transaction fee | ||
- A deposit (an even number, 0 is accepted). | ||
- An amount (aeons to transfer to the account, 0 is accepted). | ||
- Gas for the initial call | ||
- Gas price for the call. | ||
- Call data for the initial call (usually including a function name and args, interpreted by the contract). | ||
|
||
|
||
``` | ||
{ owner :: public_key() | ||
, nonce :: pos_integer() | ||
, code :: hex_bytes() | ||
, vm_version :: hex_byte() | ||
, fee :: amount() | ||
, deposit :: amount() | ||
, amount :: amount() | ||
, gas :: amount() | ||
, gas_price :: amount() | ||
, call_data :: hex_bytes() | ||
} | ||
``` | ||
|
||
Where a hex byte is a string of two hex digits preceded with 0x, | ||
and hex bytes is a string of a number of hex bytes preceded with 0x. | ||
|
||
Call data is encoded depending on the ABI of the language of the contract. | ||
|
||
The transaction has to be signed with the private key of the owner. | ||
|
||
The special variable "caller" will be set to the same value as "owner" | ||
for the initial call. | ||
|
||
The contract address is created by taking the Key-length left most hex chars | ||
of | ||
|
||
``` | ||
"C0DE" && hash( nonce && owner) | ||
``` | ||
|
||
The fee, the deposit, the amount and the used gas will be | ||
subtracted from the owner account. | ||
|
||
The amount will be added to the contract account. | ||
|
||
The fee will added to the miners account. | ||
|
||
The deposit will be "held by the contract" until it is deactivated. | ||
|
||
If the initial call fails (runs out of gas) the contract is not | ||
created. The owner loses the fee and the gas (to the miner) but the | ||
amount and the deposit are return to the owner. | ||
|
||
The miner will add the new created contract address, the contract state | ||
and the return data from the initial call to the state tree (if the | ||
init succeeds). | ||
|
||
|
||
### Attach Contract Transaction | ||
|
||
Attach contract code to an existing accont. | ||
In this case owner == the acount addrres and no new account will be created, | ||
all other fields are as in create contract. | ||
|
||
|
||
``` | ||
{ owner :: public_key() | ||
, nonce :: pos_integer() | ||
, code :: hex_bytes() | ||
, vm_version :: hex_byte() | ||
, fee :: amount() | ||
, deposit :: amount() | ||
, amount :: amount() | ||
, gas :: amount() | ||
, gas_price :: amount() | ||
, call_data :: hex_bytes() | ||
} | ||
``` | ||
|
||
The special variable "caller" will be set to the same value as "owner" | ||
for the initial call. | ||
|
||
The miner will add the return data and the state from the initial call | ||
to the state tree. | ||
|
||
|
||
### Contract call transaction | ||
|
||
Anyone can call an existing contract (as long as it isn't disabled). | ||
|
||
The transaction contains: | ||
- The address of the caller (the one signing and paying for the transaction) | ||
- The address of the contract | ||
- An optional additional fee to the miner apart from gas. | ||
- Optional amount to transfer to the account before execution. | ||
- The amount of gas to use | ||
- The calldata | ||
- A transaction fee | ||
|
||
``` | ||
{ caller :: public_key() | ||
, nonce :: pos_integer() | ||
, contract :: public_key() | ||
, vm_version :: hex_byte() | ||
, fee :: amount() | ||
, amount :: amount() | ||
, gas :: amount() | ||
, gas_price :: amount() | ||
, call_data :: hex_bytes() | ||
} | ||
``` | ||
|
||
The transaction has to be signed with the private key of the caller. | ||
|
||
The call_data is encoded in accordance with the contract language ABI. | ||
(See e.g. the Ring ABI.) | ||
|
||
The miner will add the return data and the state of the call to the state | ||
tree. |
Oops, something went wrong.