Code Samples

Deploying to SKALE is similar to deploying to the Ethereum blockchain. There are a few changes you will need to make within your deployment scripts. When using these code samples, please be sure to modify the code appropriately before running anything in production!

You can share your own code sample by reaching out to us at dev@skalelabs.com.

Deployment Scripts

Use these deployment script examples to deploy your smart contracts onto your S-Chain.

Truffle Script

Truffle is a popular way to deploy your smart contracts onto Ethereum, and can also be used to deploy your smart contracts onto SKALE. You can update your truffle configuration file (truffle.js) with a configuration to deploy your smart contracts onto SKALE.

For more information on truffle configuration files, please see Truffle's Configuration Documentation.

NOTE: In order to deploy your smart contracts onto SKALE, the transaction needs to be signed. This code below shows two ways to  sign the transactions. If you prefer to sign with your MetaMask account, the truffle-hdwallet-provider package allows you to use your MetaMask mnemonic. Alternatively, if you simply want to use a private key, utilizing the truffle-privatekey-provider package will make this possible.
/*
 * This truffle script will deploy your smart contracts to your new S-Chain.
 *
 *  @param {String} mnemonic - Provide your MetaMask seed words.
 *  @param {String} privateKey - Provide your Private Key.
 *  @param {String} provider - Provide your SKALE endpoint address.
 */

// HDWalletProvider uses MetaMask to sign the smart contract deployment transaction
let HDWalletProvider = require("truffle-hdwallet-provider");
let mnemonic = "[YOUR_METAMASK_SEED_WORDS]";

// PrivateKeyProvider uses your private key sign the smart contract deployment transaction
let PrivateKeyProvider = require("truffle-privatekey-provider");
let privateKey = "[YOUR_PRIVATE_KEY]";

module.exports = {
    networks: {
        hd_wallet: {
            provider: new HDWalletProvider(mnemonic, "[YOUR_SKALE_CHAIN_ENDPOINT]"),
            gasPrice: 0,
            network_id: "*"
        },
        private_key: {
            provider: new PrivateKeyProvider(privateKey, "[YOUR_SKALE_CHAIN_ENDPOINT]"),
            gasPrice: 0,
            gas: 8000000,
            network_id: "*"
        }
    }
}
You can point your deployment scripts for your existing smart contracts to your S-Chain’s address and deploy using existing tooling (e.g.: Truffle). An example truffle deployment command to deploy your smart contracts using the 'hd_wallet network in the script above is:
truffle deploy --reset --network hd_wallet --compile-all

NodeJS Script

Smart contracts can be deployed with just the use of web3.js as well. Below you will find a simple script for using NodeJS and web3.

NOTE: Web3 and solc versions matter for compatibility. Web3 1.0.0-beta.35 and solc version 0.5.4 work well together, but other version combinations can cause unexpected errors.

For more information on using web3.js, please see Web3.js Getting StartedDocumentation.
See the full code sample on Github.
/*
 * This nodeJS script will deploy your smart contracts to your new S-Chain.
 *
 *  @param {String} private key - Provide your private key.
 *  @param {String} account - Provide your account address.
 *  @param {String} SKALE Chain endpoint - provide your SKALE Chain endpoint
 *  @param {String} contractName - Name of your smart contract (i.e. MySmartContract)
 *  @param {String} contractFileName - Complete filename of contract (i.e. MySmartContract.sol)
 */

const Web3 = require('web3'); // version 1.0.0-beta.35
const solc = require('solc'); // version 0.5.4
const path = require('path');
const fs = require('fs');

let privateKey = "[YOUR_PRIVATE_KEY]";
let account = "[YOUR_ACCOUNT_ADDRESS]";
let schainEndpoint = "[YOUR_SKALE_CHAIN_ENDPOINT]";

let contractName = "HelloSKALE"; //replace with your contract name
let contractFileName = "HelloSKALE.sol"; //replace with the filename of the contract

//Retrieve and compile contract source code
const contractPath = path.resolve(__dirname, 'contracts', contractFileName);
const contractContent = fs.readFileSync(contractPath, 'UTF-8');

//Format contract for solc reader
var contracts = {
  language: 'Solidity',
  sources: {},
  settings: {
    outputSelection: {
      '*': {
        '*': [ '*' ]
      }
    }
  }
}

//add HelloSKALE contract to contract sources
contracts.sources[contractFileName] = { content: contractContent };

//compile data via solc reader
let solcOutput = JSON.parse(solc.compile(JSON.stringify(contracts)));

//get compile HelloSKALE contract
let contractCompiled = solcOutput.contracts[contractFileName][contractName];

//Connect Web3 to your SKALE Chain
const web3 = new Web3(new Web3.providers.HttpProvider(schainEndpoint));


//create transaction 
var tx = {
  data : '0x' + contractCompiled.evm.bytecode.object,
  from: account, 
  gasPrice: 0,
  gas: 80000000
};

//sign transaction to deploy contract
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
  web3.eth.sendSignedTransaction(signed.rawTransaction).
    on('receipt', receipt => {
     console.log(receipt)
   }).
    catch(console.error);
});
You can point your deployment scripts for your existing smart contracts to your S-Chain’s address and deploy using existing tooling (e.g.: Truffle). An example truffle deployment command to deploy your smart contracts using the 'hd_wallet network in the script above is:
truffle deploy --reset --network hd_wallet --compile-all

Money Transfer Scripts

Use these script examples to make deposits into your Deposit Box, or to exit funds from your SKALE Chain.
See the full code sample on Github.

Deposit Funds Script

This method is called from the private SKALE testnet to "freeze" funds and move money into a safe Deposit Box.
/*
 * This nodeJS script will deposit funds into your SKALE Deposit Box.
 *
 *  @param {String} private key - Provide your private key.
 *  @param {String} account - Provide your account address.
 *  @param {String} Private SKALE testnet endpoint - provide the private SKALE testnet endpoint
 *  @param {String} SKALE Chain id - provide your SKALE Chain id
 */

const Web3 = require('web3');
const mainnetJson = require("./contracts/mainnet_proxy.json");
const Tx = require('ethereumjs-tx');

let privateKey = new Buffer('[YOUR_PRIVATE_KEY]', 'hex')
let account = "[YOUR_ACCOUNT_ADDRESS]";
let privateSkaleTestnetEndpoint = "[PRIVATE_SKALE_TESTNET_ENDPOINT]";
let schainID = "[YOUR_SKALE_CHAIN_ID]";

const depositBoxAddress = mainnetJson.deposit_box_address;
const abi = mainnetJson.deposit_box_abi;

const web3 = new Web3(new Web3.providers.HttpProvider(privateSkaleTestnetEndpoint));

let contract = new web3.eth.Contract(abi, depositBoxAddress);

//prepare the smart contract function deposit(string schainID, address to)
let deposit = contract.methods.deposit(schainID, account).encodeABI();  

//get nonce
web3.eth.getTransactionCount(account).then(nonce => {
  
  //create raw transaction
  const rawTx = {
    from: account, 
    nonce: "0x" + nonce.toString(16),
    data : deposit,
    to: depositBoxAddress,
    gasPrice: 0,
    gas: 8000000,
    value: web3.utils.toHex(web3.utils.toWei('1', 'ether'))
  }

  //sign transaction
  const tx = new Tx(rawTx);
  tx.sign(privateKey);

  const serializedTx = tx.serialize();

  //send signed transaction
  web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).
    on('receipt', receipt => {
      console.log(receipt);
      web3.eth.getBalance(depositBoxAddress)
      .then((balance) => { console.log("Balance in Deposit Box: " + 
          web3.utils.fromWei(balance, 'ether'))
      });
   }).
    catch(console.error);
});

Exit Script

This method is called from the SKALE Chain to "release" funds and exit back to the end user on the private SKALE testnet.
/*
 * This nodeJS script will allow you to remove funds from the Deposit Box..
 *
 *  @param {String} private key - Provide your private key.
 *  @param {String} account - Provide your account address.
 *  @param {String} SKALE Chain endpoint - provide your SKALE Chain endpoint
 *  @param {String} SKALE Chain id - provide your SKALE Chain id
 */

const Web3 = require('web3');
const schainJson = require("./contracts/schain_proxy.json");

const Tx = require('ethereumjs-tx');

let privateKey = new Buffer('[YOUR_PRIVATE_KEY]', 'hex')
let account = "[YOUR_ACCOUNT_ADDRESS]";
let schainEndpoint = "[YOUR_SKALE_CHAIN_ENDPOINT]";

const tokenManagerAddress = schainJson.token_manager_address;
const abi = schainJson.token_manager_abi;

const web3 = new Web3(new Web3.providers.HttpProvider(schainEndpoint));

let contract = new web3.eth.Contract(abi, tokenManagerAddress);

//prepare the smart contract function exitToMain(address to)
let exitToMain = contract.methods.exitToMain(account).encodeABI();  

web3.eth.getTransactionCount(account).then(nonce => {
  const rawTx = {
    nonce: nonce,
    from: account, 
    nonce: "0x" + nonce.toString(16),
    data : exitToMain,
    to: tokenManagerAddress,
    gasPrice: 0,
    gas: 8000000,
    value: web3.utils.toHex(web3.utils.toWei('1', 'ether'))
  }

  const tx = new Tx(rawTx);
  tx.sign(privateKey);

const serializedTx = tx.serialize();

  //send signed transaction
  web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).
    on('receipt', receipt => {
      console.log(receipt);
      web3.eth.getBalance(account)
      .then((balance) => { console.log("Balance in Deposit Box: " + 
          web3.utils.fromWei(balance, 'ether'))
      });
   }).
    catch(console.error);
});