Skip to content

Web3c.js: An Oasis Extension to Web3.js

For convenience, we provide a web3c.js client library that communicates with contracts on Oasis. Here we'll explore two new features:

  • confidentiality
  • contract storage expiry

Note that this library includes and is modeled after web3.js 1.0 so that your web application can interact with Oasis contracts using the same programming model. However, we've extended the library to have Oasis-specific functionality in the web3c.oasis namespace, in addition to the existing backwards-compatible web3c.eth namespace.

Interacting with Confidential Smart Contracts from your DApp

Transactions to confidential smart contracts are encrypted end-to-end such that only the caller and the smart contract can decrypt transaction contents.

Unfortunately, standard Web3 is designed for non-confidential platforms in which all data is public. Existing Web3 libraries therefore do not provide the requisite security primitives for interacting with confidential smart contracts.

To address these limitations we have developed an extension to Web3 called Web3c (Web3 Confidential) to enable applications to interact with confidential smart contracts securely.

For example, observe the following contract using the web3c.js Oasis Contract object.

const confidentialContract = new web3c.oasis.Contract(MyContract.abi, MyContract.address, options);

Here we've created a handle to a confidential smart contract using the web3c.oasis.Contract interface with all the same APIs as web3.eth.Contract. The only difference is that, in the web3c.oasis namespace by default, web3c.js wraps the underlying RPC calls with encryption and decryption, allowing one to securely communicate with confidential smart contracts.

Once you construct a handle using web3c.oasis.Contract, you can interact with the confidential smart contract in the same way as a non-confidential contract by calling methods on the object. For example,

// Sends a transaction, invoking the `myMethod` function on the given contract.
await confidentialContract.methods.myMethod().send();

Note that the Oasis web3c.oasis namespace requires a promise-based asynchronous programming model, and so callbacks are not supported. You can see more examples in the Oasis Box test script, which interacts with both confidential and non-confidential contracts using identical code, the only difference being the use of the web3c.eth.Contract constructor.

Now let's explore the features in web3c.js specific to the Oasis Devnet.

Contract Settings

At deploy time, you can specify a "contract header" as a JSON object that will determine how the contract is managed by the Oasis runtime environment.

field type default description
expiry integer 100 years from now When the contract should expire as a Unix timestamp (i.e. seconds since Jan 1, 1970)
confidential boolean true Whether the smart contract is confidential

For example, to deploy a non-confidential smart contract with a 24-hour lifetime:

let contract = await new web3c.oasis.Contract(
  CONTRACT_ABI,
  undefined, // no contract address since we're deploying
  options    // default transaction options for this Contract
}).deploy({
  data: CONTRACT_INITCODE, // evm or wasm initcode
  arguments: [...],        // contract-specific constructor args
  header: {
    confidential: false,
    expiry: Math.floor(Date.now()/1000) + 24*60*60, // expire in 24 hours
  }
}).send();

Recall that contracts in the web3c.oasis namespace are confidential by default. You must explicitly turn off confidentiality to disable encryption. When using the web3c.eth namespace, everything works in the same way as vanilla web3.js without modification.

Checking a Contract's Expiration Time

To check the expiration time of a deployed contract, simply use the expiry function on the deployed contract instance:

await contract.expiry();

Alternatively, if you don't have a contract object but you have the address, we can use

web3c.oasis.expiry(CONTRACT_ADDRESS)

Under the hood

Contracts with custom expiry, as well as confidential contracts, are deployed using the standard eth_sendTransaction web3 API. However, they are distinguished from normal contracts by a header prepended to their bytecode. The prefix \0sis on contract bytecode indicates that a contract deployment header follows. The header format is as follows: 2 bytes encoding the header version, 2 bytes encoding the length of the header contents, then a serialized JSON map with allowed keys confidential (boolean) and expiry (integer).

Using Web3c.js

We provide a hosted version of the latest version of Web3c.js that you can use in your web application:

<script src="https://cdn.oasiscloud.io/web3c-latest/web3c.js"></script>

You can also install via npm:

npm install --save web3c

Alternatively you can download the library from the Github repository.

Deploying Confidential Smart Contracts

Any contract can be deployed confidentially (Solidity or Rust). There are several ways to do this depending on your preferred toolchain:

  • Using Web3c.js. Web3c.js provides methods for deploying smart contracts with confidentiality in the same manner as web3.js. For example,
new web3c.oasis.Contract(
  CONTRACT_ABI,
  undefined, // no contract address since we're deploying
  options    // default transaction options for this Contract
}).deploy({
  data: CONTRACT_INITCODE, // evm or wasm initcode
  arguments: [...],        // contract-specific constructor args
  header: {
    confidential: true,
    expiry: Math.floor(Date.now()/1000) + 24*60*60, // expire in 24 hours
  }
}).send();

For more information, see the web3.js documentation.

  • Using Truffle. When using Truffle with the Oasis Contract Kit, you can add a migration script with the following to deploy a confidential smart contract:
// 2_counter_migration.js
const Counter = artifacts.require("Counter");
module.exports = function(deployer) {
  deployer.deploy(ConfidentialCounter, {
    oasis: {
        confidential: true,
        expiry: Math.floor(Date.now()/1000) + 24*60*60, // expire in 24 hours
      }
  });
}

Note that the oasis options passed in must be the last argument to the deployer.deploy function.

For more information about using Truffle with confidential smart contracts, see this page.

You can verify your contract was deployed as a confidential smart contract by viewing the account details in the Oasis Explorer. Confidential smart contracts are denoted with a padlock icon as shown below:

Confidential Smart Contract