GardenBlockchain

A Solidity convention notebook, with rules kept in context

An older repository layout and formatting workflow, separated from compiler behavior and security guarantees.

A shared convention helps readers find the relevant contract and compare changes. The original notebook proposed a source layout, formatting/lint checks, and naming rules. Those are local conventions, separate from compiler guarantees or security review.

Keep working and reference material distinct

- src
    /active: For working contracts
        /interfaces: Contains all contract interface type
        /libraries: Contains all library type
        /utils: Contains all utility type
        XXXToken.sol: ERC20 token
    /archived: For reference, sample contract, etc
    /stash: Temporary contract storage. This contract can be moved to `active` for deployment

Deployment tooling still needs an explicit selection of contracts. A folder name alone does not prevent an archived contract from being compiled or deployed.

Format and lint with a known toolchain

"prettier": "^2.4.0",
"prettier-plugin-solidity": "^1.0.0-beta.18",
"solhint": "^3.3.6",
"solhint-plugin-prettier": "^0.0.5"
Inspect the earlier package and hook setup
// package.json
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "lint": "./node_modules/.bin/solhint -f table 'src/active/**/*.sol' -w 0",
    "format": "./node_modules/.bin/prettier --write 'src/active/**/*.sol'",
    "prepare": "husky install"
  },
  "devDependencies": {
  ....
    "husky": "^7.0.2",
    "prettier": "^2.4.0",
    "prettier-plugin-solidity": "^1.0.0-beta.18",
    "pretty-quick": "^3.1.1",
    "solhint": "^3.3.6",
    "solhint-plugin-prettier": "^0.0.5"
  }


// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx pretty-quick --staged && npm run lint
npm run format
npm run lint

These version ranges and Husky commands are historical. A formatting or lint result does not replace functional tests; the displayed package fragment explicitly has no implemented test script. The optional external semantic-commit Gist was unavailable during retrieval, so its text is not incorporated.

Make the convention readable

The source grouped declarations and related functions, then applied prefixes and suffixes consistently:

    1. Variables: Struct -> constant -> private -> public
    2. Events
    3. Constructor/Initializer
    2. Modifiers
    4. Function: Sort by order of function required (not visibitity)
      Ex:
      function0() {x = function1();}

      // Function 1 called in function, it will be below function0()
      function1() {}

    5. Group function by public/private. The private group should place at end of the file.
    + Global public: normal without prefix or suffix (Ex: name)
    + Global private: Prefix _ (Ex: _name)
    + Function params: Prefix _ (Ex: _pName)
    + Function returns: Prefix _ (Ex: _rName)
    + Function local vars: Suffix _ (Ex: name_)
    + Function public name: Prefix f (Ex: fName() )
    + Function private name: Refix _f (Ex: _fName() )
    + Modifier name: Prefix m (Ex: mRestricted() )

Its numbering is retained from the notebook. These prefixes are a local vocabulary rather than a Solidity requirement. Comments should explain constraints, authority, or intent with correct grammar; commenting every obvious assignment adds little.

Separate style from correctness

Bounded array access, clear privilege boundaries, meaningful configuration events, and intentional zero-address handling are design concerns. Whether zero is valid depends on the operation; the source itself allowed zero to remove a presenter.

The note’s absolute claims about modifier cost, visibility order saving gas, and arrays in public structs are not universal rules. Compiler version and generated code matter. A multisignature or access-control library also does not automatically decentralize authority. No hook, package, contract, or repository convention was applied by this article rewrite.

← Back to the garden