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.