Home SASEUL JS Specification
Post
Cancel

Specification

Quick Start

npm

1
$ npm install saseul
1
2
3
4
const SASEUL = require('saseul');
let key = SASEUL.Sign.keyPair();
console.dir(key);
... 

Browser

1
2
3
4
5
6
7
8
9
10
11
12
...

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tweetnacl/1.0.2/nacl.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.5/axios.min.js"></script>
<script type="text/javascript" src="saseul.min.js"></script>

<script type="text/javascript">
    let key = SASEUL.Sign.keyPair();
    console.dir(key);
</script>
...


Generating Key pair, Address and Signature

SASEUL use ed25519, ripemd160, sha256 algorithm to make private key, public key, address. Ed25519 is used to generate key pairs. You can hash the public key generated by the ed25519 algorithm as follows to generate an address.

  • address = ID_HASH(public_key)
  • ID_HASH = SHORT_HASH + CHECKSUM
  • CHECKSHUM = SHA256(SHA256(SHORT_HASH)).SUBSTRING(0,4)
  • SHORT_HASH = RIPEMD160(SHA256(public_key))

SASEUL.Sign.keyPair

Generate a key pair.

1
2
3
4
5
6
7
8
9
let key = SASEUL.Sign.keyPair();
console.dir(key);

// result:
{
    "private_key": "<PRIVATE_KEY>",
    "public_key": "<PUBLIC_KEY>",
    "address": "<ADDRESS>"
}

SASEUL.Sign.privateKey

Generate only a private key.

1
2
3
4
5
let key = SASEUL.Sign.privateKey();
console.dir(key);

// result:
<PRIVATE_KEY>

SASEUL.Sign.publicKey

Generate a public key from the private key.

1
2
3
4
5
let key = SASEUL.Sign.publicKey("<PRIVATE_KEY>");
console.dir(key);

// result:
<PUBLIC_KEY>

SASEUL.Sign.address

Generate an address from the public key.

1
2
3
4
5
let address = SASEUL.Sign.address("<PUBLIC_KEY>");
console.dir(address);

// result:
<ADDRESS>

SASEUL.Sign.addressValidity

Return the validity of the address.

1
2
3
4
5
let validity = SASEUL.Sign.addressValidity("<ADDRESS>");
console.dir(validity);

// result:
    true or false

SASEUL.Sign.signature

Generate a signature from contents and private Key.

The data type of ‘' can be any type.

1
2
3
4
5
let signature = SASEUL.Sign.signature(<CONTENTS>, "<PRIVATE_KEY>");
console.dir(signature);

// result:
<SIGNATURE>

SASEUL.Sign.signatureValidity

Return the validity of the signature.

1
2
3
4
5
let validity = SASEUL.Sign.signatureValidity(<CONTENTS>, "<PUBLIC_KEY>", "<SIGNATURE>"),
console.dir(validity);

// result:
    true or false

SASEUL.Sign.keyValidity

Return the validity of the key.

1
2
3
4
5
let validity = SASEUL.Sign.keyValidity("<PRIVATE_KEY OR PUBLIC_KEY>"),
console.dir(validity);

// result:
    true or false


Creating and Sending Transactions and Requests

When a transaction is sent to the network, the network processes the transaction with the contract code and returns the result.

When a request is sent to the network, the network queries the current state data and returns the result.

SASEUL.Rpc.endpoint (Deprecated)

Set the endpoint for sending transactions and requests to a node.

Please use the SASEUL.Rpc.endpoints function instead.

1
SASEUL.Rpc.endpoint('<ENDPOINT>');

SASEUL.Rpc.endpoints

Set the endpoints for sending transactions and requests to nodes.

1
2
SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);

SASEUL.Rpc.timeout

Set the timeout duration when sending transactions or requests to nodes.

The default value is 30 seconds.

1
SASEUL.Rpc.timeout('<milliseconds>');

SASEUL.Rpc.headers

Set the headers to be used when sending transactions or requests to nodes.

1
SASEUL.Rpc.headers('<HEADERS>');

SASEUL.Rpc.tracker

Retrieve tracker information from one of the nodes at the set endpoints.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.tracker().then(function (r) { console.dir(r); });

// result:
{
  "code": 200,
  "data": {
    "peers": {
        ...
    },
    "known_hosts": [
        ...
    ]
  }
}

SASEUL.Rpc.trackerFromAll

Collect tracker information from all set endpoints and return the merged tracker information.

1
2
3
4
5
6
7
8
9
10
11
12
SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.trackerFromAll().then(function (r) { console.dir(r); });

// result:
{
  "peers": {
    ...
  },
  "known_hosts": [
    ...
  ]
}

SASEUL.Rpc.peer

Retrieve peer information from one of the nodes at the set endpoints.

1
2
3
4
5
6
7
8
9
10
11
SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.peer().then(function (r) { console.dir(r); });

// result:
[
    {
        "host": "<ENDPOINT>",
        "address": "<PEER_ADDRESS>"
    },
    ...
]

SASEUL.Rpc.peerFromAll

Collect peer information from all set endpoints and return the merged peer information.

1
2
3
4
5
6
7
8
9
10
11
SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.peerFromAll().then(function (r) { console.dir(r); });

// result:
[
    {
        "host": "<ENDPOINT>",
        "address": "<PEER_ADDRESS>"
    },
    ...
]

SASEUL.Rpc.ping

Check if the node is alive.

1
2
3
4
5
6
7
8
SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.ping().then(function (r) { console.dir(r); });

// result:
{
    "code": 200,
    "data": "ok"
}

SASEUL.Rpc.round

Retrieve the current chain status from one of the nodes at the set endpoints.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.round().then(function (r) { console.dir(r); });

// result:
{
  "code": 200,
  "data": {
    "main": {
        ...
    },
    "resource": {
        ...
    }
  }
}

SASEUL.Rpc.bestRound

Retrieve the current chain status from all set endpoints and return the best chain status information.

1
2
3
4
5
6
7
8
9
10
11
12
SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.bestRound().then(function (r) { console.dir(r); });

// result:
{
  "main": {
    ...
  },
  "resource": {
    ...
  }
}

SASEUL.Rpc.signedRequest

Create a signed request from data and a private key.

1
2
3
4
5
6
7
8
9
10
11
12
let obj = SASEUL.Rpc.signedRequest({ type : "GetBalance", address: "<ADDRESS>"}, SASEUL.Sign.privateKey());
console.dir(obj);

// result:
{
    "request": {
        "type": "GetBalance",
        ...
    },
    "public_key": "...",
    "signature": "..."
}

SASEUL.Rpc.simpleRequest

Create an unsigned simple request object.

1
2
3
4
5
6
7
8
9
10
let obj = SASEUL.Rpc.simpleRequest({ type : "GetBalance", address: "<ADDRESS>"});
console.dir(obj);

// result:
{
    "request": {
        "type": "GetBalance",
        ...
    }
}

SASEUL.Rpc.signedTransaction

Create a signed transaction from data and a private key.

1
2
3
4
5
6
7
8
9
10
11
12
let obj = SASEUL.Rpc.signedTransaction({ type: "Send", to: "<ADDRESS>", amount: "<AMOUNT>"}, SASEUL.Sign.privateKey());
console.dir(obj);

// result:
{
    "transaction": {
        "type": "Send",
        ...
    },
    "public_key": "...",
    "signature": "..."
}

SASEUL.Rpc.request

Send a signed request or a simple request to one of the nodes at the set endpoints and return the result.

1
2
3
4
5
6
7
8
9
10
11
12
let obj = SASEUL.Rpc.signedRequest({ type : "GetBalance", address: "<ADDRESS>"}, SASEUL.Sign.privateKey());

SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.request(obj).then(function (r) { console.dir(r); });

// result:
{
    "code": 200,
    "data": {
        "balance": "..."
    }
}

SASEUL.Rpc.raceRequest

Send a signed request or a simple request to all set endpoints and return the result from the endpoint that responds the fastest and meets the condition.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.bestRound().then(results => {
    let obj = SASEUL.Rpc.simpleRequest({ type: "ListBlock", page: 1, count: 5 });
    let condition = (blocks) => {
        let latest = Object.values(blocks).reduce((prev, curr) => curr.height > prev.height ? curr : prev);

        return latest.height >= results.main.height;
    }
    
    SASEUL.Rpc.raceRequest(obj, condition).then(function (r) {
        console.dir(r);
    });
});

// result:
{
    "code": 200,
    "data": {
        // BLOCK DATAS
        ...
    }
}

SASEUL.Rpc.sendTransaction

Send a signed transaction to one of the nodes at the set endpoints and return the result.

1
2
3
4
5
6
7
8
9
10
let obj = SASEUL.Rpc.signedTransaction({ type: "Send", to: "<ADDRESS>", amount: "<AMOUNT>"}, SASEUL.Sign.privateKey());

SASEUL.Rpc.endpoints('<ENDPOINT>');
SASEUL.Rpc.sendTransaction(obj).then(function (r) { console.dir(r); });

// result:
{
    "code": 200,
    "data": ...
}

SASEUL.Rpc.sendTransactionToAll

Send a signed transaction to all set endpoints and return the result for each endpoint.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let obj = SASEUL.Rpc.signedTransaction({ type: "Send", to: "<ADDRESS>", amount: "<AMOUNT>"}, SASEUL.Sign.privateKey());

SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.sendTransaction(obj).then(function (r) { console.dir(r); });

// result:
{
    {
        "code": 200,
        "data": ...
        "endpoint": "<ENDPOINT1>"
    },

    ...
}

SASEUL.Rpc.broadcastLimit

Set the maximum number of simultaneous broadcasts when broadcasting transactions to nodes.

The default value is 32.

1
SASEUL.Rpc.broadcastLimit('<limit>');

SASEUL.Rpc.broadcastTransaction

Broadcast a signed transaction and return the result. The number of times the transaction is broadcast depends on the number of peers of the node.

1
2
3
4
5
6
7
8
9
10
let obj = SASEUL.Rpc.signedTransaction({ type: "Send", to: "<ADDRESS>", amount: "<AMOUNT>"}, SASEUL.Sign.privateKey());

SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.broadcastTransaction(obj).then(function (r) { console.dir(r); });

// result:
{
    "code": 200,
    "data": ...
}

SASEUL.Rpc.estimatedFee

Estimate the transaction fee. It returns an accurate fee only for valid transaction.

1
2
3
4
5
6
7
let obj = SASEUL.Rpc.signedTransaction({ type : "Send", to: "<ADDRESS>", amount: "<AMOUNT>"}, SASEUL.Sign.privateKey());

SASEUL.Rpc.endpoints(["<ENDPOINT1>", "<ENDPOINT2>", "<ENDPOINT3>", ...]);
SASEUL.Rpc.estimatedFee(obj).then(function (r) { console.dir(r); });

// result:
738000000000

Cryptographic Hash Functions

These functions provide essential cryptographic hash operations for the SASEUL network.

They include generating hash values using SHA-256 and RIPEMD-160 algorithms, converting data to string format, generating checksums, and deriving cryptographic identifiers such as address hashes, smart contract IDs, and transaction hashes.

SASEUL.Enc.string

Convert a given value to a string.

1
2
3
4
5
let result = SASEUL.Enc.string({});
console.dir(result);

// result:
"{}"

SASEUL.Enc.hash

Convert a given value to a SHA-256 hash. It must return a 64-character string.

1
2
3
4
5
let result = SASEUL.Enc.hash({});
console.dir(result);

// result:
44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a

SASEUL.Enc.shortHash

Convert a given value to a SHA-256 hash and then to a RIPEMP160 hash. It must return a 40-character string.

1
2
3
4
5
let result = SASEUL.Enc.shortHash({});
console.dir(result);

// result:
62b7341d7271ea3b5ad12011a9467d8ba2736623

SASEUL.Enc.checksum

Generate a checksum of a given value. It must return a 4-character string.

1
2
3
4
5
let result = SASEUL.Enc.checksum("62b7341d7271ea3b5ad12011a9467d8ba2736623");
console.dir(result);

// result:
be3b

SASEUL.Enc.hextime

Convert a time in microseconds to a hexadecimal time. It must return a 14-character string.

1
2
3
4
5
let result = SASEUL.Enc.hextime(1681133629023000);
console.dir(result);

// result:
05f8fb6cc72318

SASEUL.Enc.timeHash

Calculate the time hash from a given value and the time in microseconds. It must return a 78-character string.

1
2
3
4
5
let result = SASEUL.Enc.timeHash({}, 1681133629023000);
console.dir(result);

// result:
05f8fb6cc7231844136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a

SASEUL.Enc.timeHashValidity

Return the validity of the time hash.

1
2
3
4
5
let result = SASEUL.Enc.timeHashValidity("05f8fb6cc7231844136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a");
console.dir(result);

// result:
    true or false

SASEUL.Enc.idHash

Calculate the address hash from a given value. It must return a 44-character string.

1
2
3
4
5
let result = SASEUL.Enc.idHash({});
console.dir(result);

// result:
62b7341d7271ea3b5ad12011a9467d8ba2736623be3b

SASEUL.Enc.idHashValidity

Return the validity of the address hash.

1
2
3
4
5
let result = SASEUL.Enc.idHashValidity("62b7341d7271ea3b5ad12011a9467d8ba2736623be3b");
console.dir(result);

// result:
    true or false

SASEUL.Enc.cid

Calculate the logical space value where a smart contract will be located from the address hash and an arbitrary string. It must return a 64-character string.

1
2
3
4
5
let result = SASEUL.Enc.cid("62b7341d7271ea3b5ad12011a9467d8ba2736623be3b", "Lorem ipsum");
console.dir(result);

// result:
d744acf8717720d74c0b0ab4855c55653556152362c4be123b3fbeb4102ac9c1

SASEUL.Enc.txHash

Calculate the transaction hash from a given data. It must return a 78-character string.

1
2
3
4
5
let result = SASEUL.Enc.txHash({"type":"Send","timestamp":1681133629023000});
console.dir(result);

// result:
05f8fb6cc72318a9fc84110f7de17f7749d414e559a68751ccde7ce76f5f0634dac05cbb3e159b

SASEUL.Enc.isHex

Check if a given value is a hexadecimal string.

1
2
3
4
5
let result = SASEUL.Enc.isHex("62b7341d7271ea3b5ad12011a9467d8ba2736623");
console.dir(result);

// result:
    true or false


Utility functions

These are functions that may be necessary during the process of data processing based on the SASEUL network.

SASEUL.Util.time

Return the current time in seconds.

1
2
3
4
5
let result = SASEUL.Util.time();
console.dir(result);

// result:
1681660939

SASEUL.Util.utime

Return the current time in microseconds.

1
2
3
4
5
let result = SASEUL.Util.utime();
console.dir(result);

// result:
1681660939642000

SASEUL.Util.randomHexString

Generate a random hexadecimal string of a given length.

1
2
3
4
5
let result = SASEUL.Util.randomHexString(16);
console.dir(result);

// result:
0e1e2770405d168a4fe246fd6469e9da

SASEUL.Util.hexToByte

Convert a hexadecimal string to a byte array.

1
2
3
4
5
let result = SASEUL.Util.hexToByte("0e1e2770405d168a4fe246fd6469e9da");
console.dir(result);

// result:
{...}

SASEUL.Util.byteToHex

Convert a byte array to a hexadecimal string.

1
2
3
4
5
let result = SASEUL.Util.byteToHex([...]);
console.dir(result);

// result:
4d8ba12d63613dda822a69bc5ac1c589

SASEUL.Util.stringToByte

Convert a regular string to a byte array.

1
2
3
4
5
let result = SASEUL.Util.stringToByte("Lorem ipsum");
console.dir(result);

// result:
{...}

SASEUL.Util.stringToUnicode

Convert a regular string to a Unicode string.

1
2
3
4
5
let result = SASEUL.Util.stringToUnicode("다람쥐헌쳇바퀴에타고파");
console.dir(result);

// result:
\\ub2e4\\ub78c\\uc950\\ud5cc\\uccc7\\ubc14\\ud034\\uc5d0\\ud0c0\\uace0\\ud30c


Create and register smart contracts

The contract language of the SASEUL engine is designed to be similar to functional programming languages. As coding according to this syntax can be very difficult, we provide tools to allow coding contracts in JavaScript. However, this page only provides a simple specification, and for detailed contract writing methods, please refer to the following documentation.

Link: Smart Contract: Operator

Note: These functions do not work in a browser environment.

SASEUL.SmartContract.Operator

Returns operator tools. For detailed information, please refer to the referenced documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const SASEUL = require('saseul');

let op = SASEUL.SmartContract.Operator;

let from = op.load_param('from');
let amount = op.load_param('amount');
let token_id = op.load_param('token_id');

let from_balance = op.read_universal(token_id, from, '0');

let condition = op.gte(from_balance, amount);
let err_msg = 'err_msg ';
let execution = op.condition(condition, err_msg);

console.dir(execution);

// result
'{"$condition":[{"$gte":[{"$read_universal":[{"$load_param":["token_id"]}, ... }'

SASEUL.SmartContract.Method

Creates a method object. For detailed information, please refer to the referenced documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const SASEUL = require('saseul');

let method = new SASEUL.SmartContract.Method({
    "type": "contract",
    "name": "Send",
    "version": "1",
    "space": '<SPACE>',
    "writer": '<ADDRESS>',
});

method.addParameter({
    "name": "token_id", 
    "type": "string", "maxlength": SASEUL.Enc.HASH_SIZE, "requirements": true
});

method.addParameter({
    "name": "to",
    "type": "string", "maxlength": SASEUL.Enc.ID_HASH_SIZE, "requirements": true
});

method.addParameter({
    "name": "amount",
    "type": "string", "maxlength": 40, "requirements": true
});

...

console.dir(method.compile());

// result
'{"t":"contract","m":"0.2.0","n":"Send","v":"1","s":"<SPACE>","w":"","p":{"token_id": ... }'

SASEUL.SmartContract.Contract

Creates a contract object. For detailed information, please refer to the referenced documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const SASEUL = require('saseul');

SASEUL.Rpc.endpoint('<ENDPOINT>');

let contract = new SASEUL.SmartContract.Contract("<ADDRESS>", "<SPACE_NONCE>");

contract.addMethod(<METHOD1>);
contract.addMethod(<METHOD2>);
contract.addMethod(...);

contract.publish(private_key);

// result
Transaction added: ...
...
Success! ...
This post is licensed under CC BY 4.0 by the author.