Developing smart contracts using Solidity on ChainMaker offers a powerful way to build secure, scalable, and interoperable blockchain applications. This guide walks developers through the complete process of writing, compiling, and testing Solidity-based smart contracts tailored for the ChainMaker blockchain framework. Whether you're building enterprise-grade decentralized applications or exploring blockchain innovation, this resource delivers essential insights into leveraging Solidity in a non-currency (tokenless) chain environment.
👉 Discover how to deploy your first smart contract with ease
Environment Setup
Before diving into contract development, ensure your environment is properly configured. ChainMaker supports cross-platform development, making it accessible across operating systems.
Supported Platforms
ChainMaker has no strict OS requirements—development can be performed seamlessly on:
- Linux
- macOS
- Windows
No additional software dependencies are required at the system level, simplifying the setup process.
Preparing the ChainMaker Environment
To test and deploy contracts, you must have:
- A running ChainMaker node
- The CMC (ChainMaker Command-line) tool installed
The CMC tool enables interaction with the blockchain, including contract deployment and invocation. For detailed installation steps, refer to official documentation covering node setup and command-line tool configuration.
Writing Smart Contracts in Solidity
Solidity is a high-level, contract-oriented programming language influenced by C++, Python, and JavaScript. It's statically typed and supports advanced features like inheritance, libraries, and custom data types—ideal for writing robust smart contracts.
Development Environment Options
Developers don't need to set up local tooling from scratch. Instead, use Remix, an online IDE widely adopted in the Ethereum ecosystem:
👉 Start coding your smart contract instantly in-browser
Remix provides syntax highlighting, debugging tools, and built-in compiler support. Importantly, ChainMaker is fully compatible with Solidity code developed in Remix, meaning Ethereum-originated contracts can often be deployed on ChainMaker with minimal or no modifications.
Key Differences Between ChainMaker and Ethereum Solidity
While ChainMaker maintains strong compatibility with Ethereum’s EVM model, there are critical distinctions due to its tokenless architecture and enterprise focus.
Built-in Global Variables and Functions
Because ChainMaker does not issue native tokens, certain Ethereum-specific values default to zero or fixed constants:
| Feature | Value / Behavior |
|---|---|
msg.value | Fixed at 0 (no native token transfers) |
block.difficulty | Always returns 0 |
tx.gasprice | Fixed at 1 |
block.coinbase | Returns proposer address of current block |
Other standard variables such as block.number, block.timestamp, msg.sender, and gasleft() function as expected and can be safely used in logic.
Precompiled Contracts
Precompiled contracts optimize performance for computationally intensive operations like cryptographic hashing and elliptic curve calculations. However, ChainMaker currently does not support all Ethereum precompiles.
Unsupported precompiled functions (under development):
ecrecover(address recovery from signature)bn256Add,bn256ScalarMul,bn256Pairing(used in zkSNARKs)blake2F
Supported precompiles include:
sha256(data)– SHA-256 hashingripemd160(data)– RIPEMD-160 hashdatacopy(data)– Read-only data duplicationbigModExp(base, exp, mod)– Modular exponentiation
Ensure your contract avoids reliance on unsupported precompiles unless they are conditionally handled.
Cross-Contract Invocation
ChainMaker extends standard EVM capabilities by allowing cross-virtual machine contract calls. In addition to calling other Solidity contracts, developers can invoke contracts written in other supported languages (e.g., Go or Rust-based Wasm contracts).
This feature enhances modularity and promotes reuse across heterogeneous smart contract systems within the same network.
For implementation details, consult the official guide on cross-contract invocation patterns.
Sample Contract: ERC20-Compatible Token
Despite being a tokenless chain, ChainMaker supports token-like logic for asset tracking and permissions management. Below is a simplified ERC20-compliant token implementation:
pragma solidity >0.5.11;
contract Token {
string public name = "token";
string public symbol = "TK";
uint256 public decimals = 6;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 public totalSupply = 0;
bool public stopped = false;
address owner = address(0x0);
modifier isOwner {
assert(owner == msg.sender);
_;
}
modifier isRunning {
assert(!stopped);
_;
}
modifier validAddress {
assert(address(0x0) != msg.sender);
_;
}
constructor(address _addressFounder) {
owner = msg.sender;
totalSupply = 100000000000000000;
balanceOf[_addressFounder] = totalSupply;
emit Transfer(address(0x0), _addressFounder, totalSupply);
}
function transfer(address _to, uint256 _value)
public
isRunning
validAddress
returns (bool success)
{
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}This example demonstrates common patterns: ownership control, modifiers for access restriction, event emission, and balance management—all fully compatible with ChainMaker’s runtime.
Compiling Contracts
Compilation transforms human-readable Solidity code into EVM-executable bytecode.
Using Docker for Compilation
ChainMaker provides an official Docker image for consistent compilation:
docker pull chainmakerofficial/chainmaker-solidity-contract:2.0.0Launch the container with volume mapping to access local files:
docker run -it --name chainmaker-solidity-contract -v $WORK_DIR:/home chainmakerofficial/chainmaker-solidity-contract:2.0.0 bashInside the container, compile using solc:
solc --abi --bin --hashes --overwrite -o . token.solOutput includes:
.bin: Binary bytecode for deployment.abi: ABI file defining method signatures.signatures: Human-readable function hashes
Compiler Version Note
The Docker image uses Solidity compiler version 0.8.4. Contracts must specify a compatible version (>=0.8.4) to prevent compilation errors.
Alternatively, use Remix to compile without version conflicts and export artifacts directly.
Testing and Simulation
Before deploying on a live network, simulate contract behavior locally.
Simulated Deployment
Use the evm command-line tool to deploy:
evm Token.bin init_contract data 00000000000000000000000013f0c1639a9931b0ce17e14c83f96d4732865b58Here:
init_contractinvokes the constructordatacontains ABI-encoded parameters (e.g., founder address)
Calldata can be generated programmatically using ChainMaker’s ABI utility package:
import "chainmaker.org/chainmaker/common/v2/evmutils/abi"
abiObj, _ := abi.JSON(strings.NewReader(string(abiBytes)))
calldata, _ := abiObj.Pack("constructorMethod", parameter)Simulated Invocation
After deployment, interact with the contract:
evm DeployedToken.bin 0x70a08231 data 0x70a08231... // balanceOf(address)Function selectors (like 0x70a08231) are derived from Keccak-256 hashes of method signatures and listed in the .signatures output file.
FAQ
Q: Can I use any version of Solidity?
A: It's recommended to use Solidity 0.8.4 or higher to match the compiler version in ChainMaker's Docker image and avoid compatibility issues.
Q: Is native token transfer supported?
A: No. ChainMaker is a tokenless chain; msg.value always returns 0 and cannot be used for fund transfers.
Q: Are all Ethereum precompiled contracts available?
A: Not all. Functions like ecrecover and BN256 operations are not yet supported but are planned for future releases.
Q: How do I generate calldata for constructor parameters?
A: Use ChainMaker’s ABI package in Go or leverage Remix IDE to encode parameters based on the contract ABI.
Q: Can I call non-Solidity contracts from my Solidity code?
A: Yes. ChainMaker supports cross-VM calls, allowing interaction between Solidity (EVM) and Wasm-based contracts.
Q: Do I need to run a full node to test contracts?
A: While a local node enables full integration testing, simulation tools like evm allow early-stage logic validation without full infrastructure.