Skip to content

Commit

Permalink
Merge pull request #118 from iotaledger/utils
Browse files Browse the repository at this point in the history
Initial tutorial
  • Loading branch information
Evaldas Drasutis authored Mar 2, 2021
2 parents 6ae938c + b492238 commit df34b04
Show file tree
Hide file tree
Showing 18 changed files with 870 additions and 148 deletions.
91 changes: 39 additions & 52 deletions contracts/rust/README.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,74 @@
## Smart Contracts

Note that most example smart contracts only show the concepts involved in creating them but should
not be taken as fully functional code.
Note that most example smart contracts only show the concepts involved in
creating them but should not be taken as fully functional code yet.

Sample smart contracts:

- dividend

Allows for setting up automatic dividend dispersal to a number of recipients according to
distribution factors per recipient. Any tokens sent to this contract will automatically be divided
accordingly over these recipients.
Allows for setting up automatic dividend dispersal to a number of recipients
according to distribution factors per recipient. Any tokens sent to this
contract will automatically be divided accordingly over these recipients.

- donatewithfeedback

Allows for donations and registers feedback associated with the donation. The contract owner can
at any point decide to withdraw donated funds from the contract.
Allows for donations and registers feedback associated with the donation. The
contract owner can at any point decide to withdraw donated funds from the
contract.

- erc20

Experimental implementation of an ERC20 smart contract as first introduced by Ethereum.
Experimental implementation of an ERC20 smart contract as first introduced by
Ethereum.

- fairauction

Allows an auctioneer to auction a number of tokens. The contract owner takes a small fee. The
contract guarantees that the tokens will be sent to the highest bidder, and that the losing
bidders will be completely refunded. Everyone involved stakes their tokens, so there is no
possibility for anyone to cheat.
Allows an auctioneer to auction a number of tokens. The contract owner takes a
small fee. The contract guarantees that the tokens will be sent to the highest
bidder, and that the losing bidders will be completely refunded. Everyone
involved stakes their tokens, so there is no possibility for anyone to cheat.

- fairroulette

A simple betting contract. Betters can bet on a random color and after a predefined time period
the contract will automatically pay the total bet amount proportionally to the bet size of the
winners.
A simple betting contract. Betters can bet on a random color and after a
predefined time period the contract will automatically pay the total bet
amount proportionally to the bet size of the winners.

- helloworld

ISCP version of the ubiquitous "Hello, world!" program.

- inccounter

A simple test contract. All it does is increment a counter value. It is also used to test basic
ISCP capabilities, like persisting state, batching requests, and sending (time-locked) requests
from a contract.
A simple test contract. All it does is increment a counter value. It is also
used to test basic ISCP capabilities, like persisting state, batching
requests, and sending (time-locked) requests from a contract.

- tokenregistry

Mints and registers colored tokens in a token registry.
- testcore

### How to create your own Go smart contracts
Helper smart contract to test the core functionality.

Building a Go smart contract is very simple when using the GoLand IntelliJ based development
environment. Open the _
wasp_ folder in your Goland, which then provides you with the Go workspace.

The easiest way to create a new contract is to copy the _helloworld.go_ file and _helloworld_ sub
folder in the _
contracts_ sub folder to properly named new copies within the _contracts_ sub folder.
- tokenregistry

To build the new smart contract select _Run->Edit Configurations_. Add a new configuration based on
the _Shell Script_
template, type the _name_ of the new configuration, select _tinygo_build.bat_
in the _wasp_ root as the _Script Path_, enter the name of the new contract as the _script options_,
and select the _
wasp_ root as the _Working Directory_, and the new folder as the _working directory_. You can now
run this configuration to compile the smart contract directly to Wasm. Once compilation is
successful you will find the resulting Wasm file in the _wasp/wasm_ folder.
Mints and registers colored tokens in a token registry.

### How to create your own Rust smart contracts

Building a Rust smart contract is very simple when using the Rust plugin in any IntelliJ based
development environment. Open the _rust_ sub folder in your IntelliJ, which then provides you with
the Rust workspace.

The easiest way to create a new contract is to copy the _helloworld_ folder in the _contracts_
sub folder to a properly named new folder within the _contracts_ sub folder. Next, change the fields
in the first section of the new folder's _cargo.toml_ file to match your preferences. Make sure the
package name equals the folder name. Finally, add the new folder to the workspace in the _
cargo.toml_ in the _rust_ sub folder.

To build the new smart contract select _Run->Edit Configurations_. Add a new configuration based on
the _wasmpack_
template, type the _name_ of the new configuration, type the _command_
`build`, and select the new folder as the _working directory_. You can now run this configuration to
compile the smart contract directly to Wasm. Once compilation is successful you will find the
Building a Rust smart contract is very simple when using the Rust plugin in any
IntelliJ based development environment. Open the _contracts/rust_ sub folder in
your IntelliJ, which then provides you with the Rust workspace.

The easiest way to create a new contract is to copy the _helloworld_ folder to a
properly named new folder within the _rust_ sub folder. Next, change the fields
in the first section of the new folder's _cargo.toml_ file to match your
preferences. Make sure the package name equals the folder name. Finally, add the
new folder to the workspace in the _cargo.toml_ in the _contracts/rust_ folder.

To build the new smart contract select _Run->Edit Configurations_. Add a new
configuration based on the _wasmpack_ template, type the _name_ of the new
configuration, type the _command_ `build`, and select the new folder as the
_working directory_. You can now run this configuration to compile the smart
contract directly to Wasm. Once compilation is successful you will find the
resulting Wasm file in the _pkg_ sub folder of the new folder.

69 changes: 69 additions & 0 deletions contracts/rust/Tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## How to write Smart Contracts for ISCP

The Iota Smart Contracts Protocol (ISCP) provides us with a very flexible way of
programming smart contracts. It does this by providing a sandboxed API that
allows you to interact with the ISCP without any security risks. The actual
implementation of the Virtual Machine (VM) that runs in the sandbox environment
is left to whomever wants to create one. Of course, we are providing an example
implementation of such a VM which allows anyone to get a taste of what it is
like to program a smart contract for the ISCP.

Our particular VM uses WebAssembly (Wasm) as in intermediate language and uses
the open source Wasmtime runtime environment to run the Wasm code. Because Wasm
code runs in its own memory space and cannot access anything outside that memory
by design, Wasm code is ideally suited for secure smart contracts. The Wasm
runtime will provide access to functionality that is needed for the smart
contracts to be able to do their thing, but nothing more. In our case all we do
is provide access to the ISCP sandbox environment.

The ISCP sandbox environment enables the following:

- Access to smart contract meta data
- Access to parameter data for smart contract functions
- Access to the smart contract state data
- A way to return data to the caller of the smart contract function
- Access to tokens owned by the smart contract and ability to move them
- Ability to call other smart contract functions
- Access to logging functionality
- Access to a number of utility functions provided by the host

Our choice of Wasm was guided by the desire to be able to program smart
contracts from any language. Since more and more languages are becoming capable
of generating the intermediate Wasm code this will eventually allow developers
to choose a language they are familiar with. To that end we designed the
interface to the ISCP sandboxed environment as a simple library that enables
access to the ISCP sandbox from within the Wasm environment. This library, for
obvious reasons, has been named WasmLib for now.

So why do we need a library to access the sandbox functionality? Why can't we
call the ISCP sandbox functions directly? The reason for that is same reason
that Wasm is secure. There is no way for the Wasm code to access any memory
outside its own memory space. Therefore, any data that is governed by the ISCP
sandbox has to be copied in and out of that memory space through well-defined
channels in the Wasm runtime. To make this whole process as seamless as possible
the WasmLib interface provides proxy objects to hide the underlying data
transfers between the separate systems.

We tried to keep things as simple and understandable as possible, and therefore
decided upon two kinds of key/value proxy objects. Arrays and maps. The
underlying ISCP sandbox provides access to its data in the form of key/value
stores that can have arbitrary byte data for both key and value. The proxy
objects channel those in easier to use data types, with the necessary type
conversions hidden within WasmLib, while still keeping the option open to use
arbitrary byte strings for keys and values.

Our initial implementation of WasmLib has been created for the Rust programming
language, because this language had the most advanced and stable support for
generating Wasm code at the time when we started implementing our Wasm VM
environment.

Here is a list of topics this tutorial will cover:

* [WasmLib Overview](wasmlib/docs/Overview.md)
* [Proxy Objects](wasmlib/docs/Proxies.md)
* [Function Call Context](wasmlib/docs/Context.md)
* [Function Parameters](wasmlib/docs/Params.md)
* [Smart Contract State](wasmlib/docs/State.md)
* [Incoming Token Transfers](wasmlib/docs/Incoming.md)
* [Limiting Access](wasmlib/docs/Access.md)
* [View Functions](wasmlib/docs/Views.md)
4 changes: 4 additions & 0 deletions contracts/rust/dividend/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ pub const SC_HNAME: ScHname = ScHname(0xcce2e239);
pub const PARAM_ADDRESS: &str = "address";
pub const PARAM_FACTOR: &str = "factor";

pub const VAR_FACTOR: &str = "factor";
pub const VAR_MEMBER_LIST: &str = "memberList";
pub const VAR_MEMBERS: &str = "members";
pub const VAR_TOTAL_FACTOR: &str = "totalFactor";

pub const FUNC_DIVIDE: &str = "divide";
pub const FUNC_MEMBER: &str = "member";
pub const VIEW_GET_FACTOR: &str = "getFactor";

pub const HFUNC_DIVIDE: ScHname = ScHname(0xc7878107);
pub const HFUNC_MEMBER: ScHname = ScHname(0xc07da2cb);
pub const HVIEW_GET_FACTOR: ScHname = ScHname(0x0ee668fe);
Loading

0 comments on commit df34b04

Please sign in to comment.