Skip to content

Commit

Permalink
Pt 154173179 contract spec (#9)
Browse files Browse the repository at this point in the history
* 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
happi authored and lucafavatella committed Feb 16, 2018
1 parent ce2af06 commit 7983223
Show file tree
Hide file tree
Showing 9 changed files with 774 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ or considered for implementation.

## [Aeternity Naming System](./AENS.md)

## [Smart Contracts](./contracts/contracts.md)

## Epoch

Epoch is the reference implementation of the Aeternity protocol. Since we don't
Expand All @@ -24,3 +26,5 @@ better solution.

- [API](./epoch/api/README.md)



144 changes: 144 additions & 0 deletions contracts/aevm.md
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.


3 changes: 3 additions & 0 deletions contracts/contract_life_cycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[back](./contracts.md)
## Contract life cycle examples

32 changes: 32 additions & 0 deletions contracts/contract_state_tree.md
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
146 changes: 146 additions & 0 deletions contracts/contract_transactions.md
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.
Loading

0 comments on commit 7983223

Please sign in to comment.