Writing simple contract
Let's look to the simple contract erc20, which were written via Ursus.
Require Import UrsusEnvironment.Solidity.current.Environment.
Require Import UrsusEnvironment.Solidity.current.LocalGenerator.
Require Import UrsusContractCreator.UrsusFieldUtils.
Require Import IERC20.
Module ERC20.
#[translation = on]
#[language = solidity]
#[Contract = ERC20Contract]
Contract ERC20 ;
Sends To IERC20;
Types ;
Constants ;
Record Contract := {
totalSupply: uint256;
balanceOf: mapping ( address )( uint256 );
allowance: mapping ( address )( mapping ( address )( uint256 ) )
}.
SetUrsusOptions.
UseLocal Definition _ := [
boolean;
address;
uint256;
(* added *)
(mapping address uint256)
].
#[override, external, nonpayable, returns=_result]
Ursus Definition transfer (recipient : address) (amount : uint256): UExpression ( boolean) false .
{
::// balanceOf[msg->sender] := balanceOf[msg->sender] - amount .
::// balanceOf[recipient] := balanceOf[recipient] + amount .
::// send IERC20.Transfer(msg->sender, recipient, amount)
=> msg->sender
with {InternalMessageParamsLRecord} [$ {2} ⇒ {Message_ι_flag} $] .
::// _result := @true |.
}
return.
Defined.
Sync.
(*...*)
EndContract Implements.
End ERC20.
First part of describing contract is require needed Pruvendo libs.
Require Import UrsusEnvironment.Solidity.current.Environment.
Require Import UrsusEnvironment.Solidity.current.LocalGenerator.
Require Import UrsusContractCreator.UrsusFieldUtils.
Next is importing file with describing Interface IERC20.
Require Import IERC20.
Next command is Contract, which should be in the module with the same name.
#[translation = on]
#[language = solidity]
#[Contract = ERC20Contract]
Contract ERC20 ;
Sends To IERC20;
Types ;
Constants ;
Record Contract := {
totalSupply: uint256;
balanceOf: mapping ( address )( uint256 );
allowance: mapping ( address )( mapping ( address )( uint256 ) );
}.
Attributes tells information about Contract: is needed tranlsation to Solidity, what is translating lang, name of raw term in Coq
#[translation = on]
#[language = solidity]
#[Contract = ERC20Contract]
Next one is command itself, which requires such as inforamation as:
- Block
describes information what interfaces are used in the contract.Send to InterfaceName1 Interface2 ... ;
- Block
declares new structures which are used in the contract.Types Record StructName1 := StructName1 { fieldName : type; ... } Record StructName2 := StructName2 { fieldName : type; ... } ...;
- Block
declares constants which are used in the contract.Constants Definition constName1: constType1 := constValue1 Definition constName2: constType2 := constValue2 ... Definition constNameN: constTypeN := constValueN ;
- Block
describes fields of current contract.Record Contract := { totalSupply: uint256; balanceOf: mapping ( address )( uint256 ); allowance: mapping ( address ) ( mapping ( address )( uint256 ) ); }.
Then tecknical command SetUrsusOptions.
comes.
Important here is command UseLocal
, more precisely
UseLocal Definition _ := [
boolean;
address;
uint256;
(mapping address uint256)
].
it declares local variables types, which will be used in functions below.
(Important !) Arguments type, return type, type of declaring variables must be in UseLocal
list!
Now let's look how we can describe function here. Example is
#[override, external, nonpayable, returns=_result]
Ursus Definition transfer (recipient : address) (amount : uint256): UExpression ( boolean) false .
{
::// balanceOf[[msg->sender]] := balanceOf[[msg->sender]] - amount .
::// balanceOf[[recipient]] := balanceOf[[recipient]] + amount .
::// send IERC20.Transfer(msg->sender, recipient, amount)
=> msg->sender
with {InternalMessageParamsLRecord} [$ {2} ⇒ {Message_ι_flag} $] .
::// _result := @true |.
}
return.
Defined.
Sync.
Main command is Ursus
, which inputs some Definition
. Attributes #[override, external, nonpayable, returns=_result]
are the same as solidity has.
(Important !) Arguments type, and return type MUST BE in the UseLocal
list!
After switching Custom foo description
to Proof mode 2 goals is here:
UExpression ( boolean) false
It's main body of function, description of it is there oops TODOIReturnExpression
goal solves via tacticreturn.
orreturn some_term.
. It has ususal semanthic like in some imperative languages.Defined.
is standart Coq command.Sync.
is needed for fast interpreting.