Writing Solidity Contracts

In this guide, we’ll walk you through writing Solidity contracts compatible with Signchain. These contracts enable secure and efficient transaction signing, seamlessly integrating with Signchain’s self-hosted or hosted vaults. This setup allows you to manage private keys securely within your own infrastructure while interacting with blockchain networks.

Prerequisites

To follow this guide, you should have:

  • Familiarity with Solidity
  • A basic understanding of Ethereum and smart contract principles
  • Access to the @grexie/signchain-contracts package, which provides interfaces for integrating with Signchain

Getting Started

To install the Signchain Solidity contracts in your project, use npm or yarn:

npm install @grexie/signchain-contracts

or

yarn add @grexie/signchain-contracts

Importing Signchain Contracts

To start, import the Signchain contracts within your Solidity file:

pragma solidity ^0.8.0;

import "@grexie/signchain-contracts/Signable.sol";

The Signable contract provides functionality for secure signing and verification.

Implementing a Signable Contract

Here’s a simple example of a contract that inherits Signable:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@grexie/signchain-contracts/Signable.sol';
import '@openzeppelin/contracts/access/Ownable.sol';

contract MySignableContract is Ownable, Signable {
  constructor(address signer_) Ownable(msg.sender) {
    _setSigner(signer_);
  }

  function setSigner(address signer_) external onlyOwner {
    _setSigner(signer_);
  }

  function executeAction(uint256 value, Signature calldata signature)
    external
    verifySignature(
      abi.encode(this.executeAction.selector, value),
      signature
    )
  {
    // Perform an action with `value` here
  }
}

Explanation

  • Signer Initialization: The signer address is set in the constructor, which is necessary for secure transaction verification. You can defer setting the signer to a second transaction you make with your contract, however signatures will fail to verify until you do this.
  • Function Security: The verifySignature modifier ensures that only signed transactions are executed by checking the validity of the signature passed with each call.

Secure Transaction Signing

To integrate Signchain’s signing system, you can use the SignOptions interface in Golang and JavaScript to securely sign transactions through Signchain’s vaults.

Example for using SignOptions:

import MyContractABI from './contract-abi.json';

const options = {
  chain: 'amoy',
  contract: myContractAddress,
  sender: userAddress,
  abi: MyContractABI,
  functionName: 'myContractFunction',
  args: [
    param1,
    param2,
    // signature <-- don't include the signature parameter
  ],
);

const { submissionHash, args } = await client.sign(options);

Testing Your Contract

Testing Signable contracts can be achieved using frameworks such as Hardhat or Truffle. You may wish to create mock functions to simulate Signchain's signing behavior and verify signatures locally.


For more information, consult the API Reference to understand all available options when working with the Signchain Vault and for setting up environment variables that enhance contract security.