Smart contracts are self-executing programs deployed on a blockchain that automatically enforce the terms of an agreement when predefined conditions are met. On Ethereum, smart contracts are written in Solidity, a statically-typed language designed specifically for the Ethereum Virtual Machine (EVM). At StrikingWeb, we have been building smart contracts for DeFi platforms, token launches, and enterprise blockchain solutions. Here is what you need to know to get started.

Understanding the Ethereum Virtual Machine

Before writing Solidity code, it is essential to understand the environment your code will run in. The EVM is a sandboxed, deterministic virtual machine that executes smart contract bytecode across every node in the Ethereum network. Key characteristics include:

Solidity Basics

Solidity's syntax is influenced by JavaScript, C++, and Python. Here is a simple example of a token contract:

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

contract SimpleToken {
    string public name = "SimpleToken";
    string public symbol = "STK";
    uint8 public decimals = 18;
    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor(uint256 _initialSupply) {
        totalSupply = _initialSupply * 10 ** uint256(decimals);
        balanceOf[msg.sender] = totalSupply;
    }

    function transfer(address _to, uint256 _value) public returns (bool) {
        require(balanceOf[msg.sender] >= _value, "Insufficient balance");
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
        return true;
    }
}

Key Concepts

Development Environment Setup

A modern Solidity development workflow typically uses one of two frameworks:

  1. Truffle: The original Ethereum development framework, offering compilation, migration scripts, testing with Mocha, and integration with Ganache for local blockchain simulation.
  2. Hardhat: A newer alternative that has gained rapid adoption thanks to its superior debugging experience (stack traces for Solidity errors), flexible plugin system, and built-in Hardhat Network for local testing.

At StrikingWeb, we currently prefer Hardhat for new projects due to its better developer experience and more active development pace. A basic Hardhat project structure looks like this:

my-contract/
  contracts/       # Solidity source files
  scripts/         # Deployment scripts
  test/            # Test files
  hardhat.config.js

Testing Smart Contracts

Testing is non-negotiable for smart contracts. Unlike traditional software, deployed contracts cannot be patched, and bugs can result in permanent loss of funds. Write tests for every function, every edge case, and every access control scenario.

const { expect } = require("chai");

describe("SimpleToken", function () {
  let token, owner, addr1;

  beforeEach(async function () {
    const Token = await ethers.getContractFactory("SimpleToken");
    [owner, addr1] = await ethers.getSigners();
    token = await Token.deploy(1000000);
  });

  it("Should assign total supply to owner", async function () {
    const ownerBalance = await token.balanceOf(owner.address);
    expect(await token.totalSupply()).to.equal(ownerBalance);
  });

  it("Should transfer tokens between accounts", async function () {
    await token.transfer(addr1.address, 50);
    expect(await token.balanceOf(addr1.address)).to.equal(50);
  });

  it("Should fail if sender has insufficient balance", async function () {
    await expect(
      token.connect(addr1).transfer(owner.address, 1)
    ).to.be.revertedWith("Insufficient balance");
  });
});

Security Considerations

Smart contract security is paramount. The most common vulnerability patterns include:

Never deploy a smart contract that handles significant value without a professional security audit. The cost of an audit is always cheaper than the cost of an exploit.

Deployment

Deploying to Ethereum mainnet involves compiling your contracts, estimating gas costs, and broadcasting the deployment transaction. Always deploy to a testnet (Ropsten, Rinkeby, or Goerli) first and thoroughly test before mainnet deployment. Verify your contract source code on Etherscan so users can independently confirm what the contract does.

Getting Started

Smart contract development is a specialised discipline that requires careful attention to security, gas optimisation, and the unique constraints of blockchain execution. If you are building a DApp, token, or DeFi protocol and need experienced Solidity developers, we are here to help you build it right.

Share: