-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* WiP * Initial documentation * Adding getting started
- Loading branch information
Showing
19 changed files
with
1,282 additions
and
17 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,137 @@ | ||
## `Address` type format | ||
|
||
The `Address` data structure in Scilla represents the 20-byte Ethereum-like | ||
address format. It is utilized to identify contracts and external accounts | ||
within the Zilliqa blockchain network. | ||
|
||
```text | ||
+--------------------+ | ||
| 20 bytes | | ||
| | | ||
| Address Payload | | ||
+--------------------+ | ||
``` | ||
|
||
Addresses are fundamental in various aspects of contract development in Scilla, | ||
such as sending and receiving funds, calling other contracts, or designating | ||
permissions. It is crucial to ensure the correctness of these addresses to | ||
prevent unintentional transactions. | ||
|
||
```scilla | ||
(* Example of contract using Scilla address *) | ||
import ListUtils | ||
contract SimpleStorage(owner: ByStr20) | ||
field storedData : Int32 = 0 | ||
transition Store(newData : Int32) | ||
is_owner = builtin eq owner _sender; | ||
match is_owner with | ||
| False => | ||
e = {_eventname : "Unauthorized"; msg : "You are not the contract owner."}; | ||
event e | ||
| True => | ||
storedData := newData; | ||
e = {_eventname : "DataStored"; data : newData}; | ||
event e | ||
end | ||
end | ||
``` | ||
|
||
## Address Verification | ||
|
||
To verify the validity of a Scilla address, one typically checks the following: | ||
|
||
1. Ensure the address has a length of 20 bytes. | ||
2. Check if the address does not contain non-hexadecimal characters. | ||
3. For contract addresses, confirm that a corresponding contract exists on the | ||
blockchain. | ||
|
||
It's also common to employ checksums to further validate addresses, though this | ||
isn't mandated by Scilla or Zilliqa. | ||
|
||
## Print `Address` | ||
|
||
The new `print` function allows developers to print the `Address` types, which | ||
is especially useful for debugging purposes. The function outputs the address in | ||
its standard hexadecimal format. | ||
|
||
```scilla | ||
(* Example of using print to display Address *) | ||
transition PrintAddress() | ||
owner_address = owner; (* Fetch the owner address *) | ||
print owner_address; | ||
end | ||
``` | ||
|
||
## Using Addresses with `zilliqa-js` | ||
|
||
The `zilliqa-js` library provides a comprehensive suite of functions to manage, | ||
validate, and work with addresses in Zilliqa's blockchain. Here's how you can | ||
work with addresses using `zilliqa-js`: | ||
|
||
### Initializing the SDK | ||
|
||
Before performing any operations, you need to initialize the SDK. | ||
|
||
```javascript | ||
const { Zilliqa } = require("@zilliqa-js/zilliqa"); | ||
const zilliqa = new Zilliqa("https://api.zilliqa.com/"); | ||
``` | ||
|
||
### **Creating a New Address** | ||
|
||
To generate a new keypair and associated address: | ||
|
||
```javascript | ||
const { getAddressFromPrivateKey } = require("@zilliqa-js/crypto"); | ||
const privateKey = zilliqa.wallet.create(); | ||
const address = getAddressFromPrivateKey(privateKey); | ||
console.log(`Address: ${address}`); | ||
``` | ||
|
||
### Validating an Address | ||
|
||
Before any operations involving an address, it's always good practice to | ||
validate it: | ||
|
||
```javascript | ||
const { validation } = require("@zilliqa-js/util"); | ||
const isValid = validation.isAddress("Your_Address_Here"); | ||
console.log(`Is valid address: ${isValid}`); | ||
``` | ||
|
||
### Converting Between Address and Bech32 | ||
|
||
Zilliqa uses the Bech32 format for human-readable addresses. Here's how to | ||
convert between a standard address and its Bech32 format: | ||
|
||
```javascript | ||
const { toBech32Address, fromBech32Address } = require("@zilliqa-js/crypto"); | ||
|
||
const bech32 = toBech32Address("Your_Address_Here"); | ||
console.log(`Bech32 format: ${bech32}`); | ||
|
||
const originalAddress = fromBech32Address(bech32); | ||
console.log(`Original format: ${originalAddress}`); | ||
``` | ||
|
||
### Using an Address in Transactions | ||
|
||
When you're sending a transaction, you'll typically need to specify the | ||
recipient's address: | ||
|
||
```javascript | ||
const tx = zilliqa.transactions.new({ | ||
toAddr: "Recipient_Address_Here", | ||
amount: zilliqa.utils.units.toQa("1", zilliqa.utils.units.Units.Zil), // 1 ZIL | ||
gasPrice: zilliqa.utils.units.toQa("1000", zilliqa.utils.units.Units.Li), // Gas Price in Li | ||
gasLimit: Long.fromNumber(50), | ||
}); | ||
``` | ||
|
||
Always remember to handle private keys securely. Avoid exposing them in | ||
client-side code or any public space. |
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,57 @@ | ||
# Contract funds | ||
|
||
## Getting the balance owned by the contract | ||
|
||
You can get the balance owned by the contract using the `_balance` keyword in | ||
Scilla. | ||
|
||
```scilla | ||
scilla_version 0 | ||
library BalanceChecker | ||
contract BalanceQuery() | ||
transition CheckBalance() | ||
current_balance <- _balance; | ||
e = { _eventname : "ContractBalance"; current_balance : current_balance }; | ||
event e | ||
end | ||
``` | ||
|
||
## Send funds from contract | ||
|
||
In Scilla, sending funds from the contract involves using the `send` | ||
instruction: | ||
|
||
```scilla | ||
scilla_version 0 | ||
library SendFunds | ||
contract SendMoney(owner: ByStr20) | ||
field balance : Uint128 = Uint128 0 | ||
transition Send(to: ByStr20, amount: Uint128) | ||
b <- _balance; | ||
can_send = builtin lt amount b; | ||
match can_send with | ||
| False => | ||
e = { _eventname : "SendFailed"; reason : "InsufficientFunds" }; | ||
event e | ||
| True => | ||
msg = { _tag : ""; _recipient : to; _amount : amount }; | ||
value = builtin sub b amount; | ||
balance := value; | ||
(* TODO: send msg; *) | ||
e = { _eventname : "SendSuccess"; recipient : to; sent_amount : amount }; | ||
event e | ||
end | ||
end | ||
``` | ||
|
||
## Advanced example | ||
|
||
TODO: Yet to be written |
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,89 @@ | ||
# Builtin functions | ||
|
||
## Builtin example usage | ||
|
||
The `eq` builtin in Scilla is used to check the equality of two values. In this | ||
example, we demonstrate how to check the equality of two Uint128 values: | ||
|
||
```scilla | ||
scilla_version 0 | ||
library EqualityCheck | ||
contract EqualityChecker() | ||
transition CheckEquality(a : Uint128, b : Uint128) | ||
(* Use builtin eq to check equality *) | ||
isEqual = builtin eq a b; | ||
e = { _eventname : "CheckEqualityResult"; result : isEqual }; | ||
event e | ||
end | ||
``` | ||
|
||
The `concat` builtin in Scilla is used to concatenate two strings. In the | ||
following example, we demonstrate how to concatenate two strings: | ||
|
||
```scilla | ||
scilla_version 0 | ||
library StringConcatContract | ||
contract StringConcat() | ||
(* Fields to store the strings and the result *) | ||
field str1 : String = "" | ||
field str2 : String = "" | ||
field result : String = "" | ||
(* Transition to set the strings *) | ||
transition SetStrings(s1: String, s2: String) | ||
str1 := s1; | ||
str2 := s2; | ||
e = { _eventname : "StringsSet"; s1 : s1; s2 : s2 }; | ||
event e | ||
end | ||
(* Transition to concatenate the stored strings *) | ||
transition ConcatenateStrings() | ||
s1 <- str1; | ||
s2 <- str2; | ||
concatenated = builtin concat s1 s2; | ||
result := concatenated; | ||
e = { _eventname : "StringsConcatenated"; concatenated : concatenated }; | ||
event e | ||
end | ||
``` | ||
|
||
With the above contracts, users can check the equality of two `Uint128` values | ||
and concatenate two strings, respectively. | ||
|
||
## Builtin summary | ||
|
||
Below is the summarized table of builtin functions: | ||
|
||
| Function name | Inputs | Outputs | Comments | | ||
| -------------------- | ---------------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------- | | ||
| `builtin eq` | `i1: IntX / UintX, i2: IntX / UintX` OR `s1: String, s2: String` | `Bool` | Checks equality between two integers or strings. | | ||
| `builtin add` | `i1: IntX / UintX, i2: IntX / UintX` | `IntX / UintX` | Adds two integer values. | | ||
| `builtin sub` | `i1: IntX / UintX, i2: IntX / UintX` | `IntX / UintX` | Subtracts the second integer from the first. | | ||
| `builtin mul` | `i1: IntX / UintX, i2: IntX / UintX` | `IntX / UintX` | Multiplies two integers. | | ||
| `builtin div` | `i1: IntX / UintX, i2: IntX / UintX` | `IntX / UintX` | Integer division. | | ||
| `builtin rem` | `i1: IntX / UintX, i2: IntX / UintX` | `IntX / UintX` | Provides the remainder after division. | | ||
| `builtin lt` | `i1: IntX / UintX, i2: IntX / UintX` | `Bool` | Checks if the first integer is less than the second. | | ||
| `builtin pow` | `i1: IntX / UintX, i2: Uint32` | `IntX / UintX` | Raises the first integer to the power of the second. | | ||
| `builtin isqrt` | `i: UintX` | `UintX` | Computes the integer square root. | | ||
| `builtin to_nat` | `i1: Uint32` | `Nat` | Converts a Uint32 value to type Nat. | | ||
| `builtin to_(u)intX` | `UintX / IntX or String` | `Option UintX / IntX` | Converts a value to a specified integer type. Can fail in certain cases. | | ||
| `builtin concat` | `s1: String, s2: String` OR `h1: ByStr(X/Y), h2: ByStr(X/Y)` | `String / ByStr` | Concatenates two strings or byte strings. | | ||
| `builtin substr` | `s: String, idx: Uint32, len: Uint32` | `String` | Extracts a substring from a given string. | | ||
| `builtin to_string` | `x: IntX, UintX, ByStrX, ByStr` | `String` | Converts various types to a string literal. | | ||
| `builtin strlen` | `s: String` OR `h: ByStr` | `Uint32` | Calculates the length of a string or byte string. | | ||
| `builtin strrev` | `s: String` | `String` | Returns the reversed version of a string. | | ||
| `builtin to_ascii` | `h: ByStr or ByStrX` | `String` | Converts a byte string to an ASCII string. Raises an error for non-printable characters. | | ||
| `builtin to_bystr` | `h: ByStrX` | `ByStr` | Converts a fixed size byte string to one of arbitrary length. | | ||
| `builtin to_bystrX` | `h: ByStr OR Uint(X)` | `Option ByStrX` | Converts an arbitrary size byte string or unsigned integer to a fixed size byte string. | | ||
| `builtin to_uintX` | `h: ByStrX` | `Uint(X)` | Converts a fixed sized byte string to an equivalent unsigned integer value. | | ||
|
||
Note: In the table, "X" and "Y" represent placeholder values, meaning you would | ||
replace them with actual numeric values (32, 64, 128, 256) as appropriate for | ||
the function's usage. |
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,55 @@ | ||
# Control flow | ||
|
||
## match | ||
|
||
The `match` construct is used for pattern matching and in place of `if` | ||
statements. It's especially useful for handling ADTs (Algebraic Data Types) and | ||
Options. | ||
|
||
Here's a simple example of using `match` with an ADT: | ||
|
||
```scilla | ||
scilla_version 0 | ||
library MatchExample | ||
type Animal = | ||
| Dog | ||
| Cat | ||
| Elephant | ||
contract AnimalSound() | ||
transition GetSound(animal: Animal) | ||
sound = | ||
match animal with | ||
| Dog => "Bark" | ||
| Cat => "Meow" | ||
| Elephant => "Trumpet" | ||
end; | ||
e = { _eventname : "AnimalSound"; sound : sound }; | ||
event e | ||
end | ||
``` | ||
|
||
Here's another example of using `match` to handle an Option type: | ||
|
||
```scilla | ||
scilla_version 0 | ||
library OptionMatchExample | ||
contract HandleOption() | ||
transition GetNumber(opt: Option Uint32) | ||
result = | ||
match opt with | ||
| Some n => n | ||
| None => Uint32 0 | ||
end; | ||
e = { _eventname : "NumberResult"; number : result }; | ||
event e | ||
end | ||
``` |
Oops, something went wrong.