Standards Mirror — TestNet Deployment Kit
This directory contains paired Solidity + Neo C# implementations of standards from the ERC ↔ Neo mirror, plus an automation script that:
- Compiles the Solidity sources with
neo-solc(built from this repo) and the C# sources withnccs(Neo.Compiler.CSharp v3.9+). - Deploys the produced NEFs to Neo N3 TestNet.
- Runs an invocation matrix (read + write) against each pair and asserts the Solidity and C# implementations behave equivalently.
- Writes structured results to
results.jsonand a Markdown summary toRESULTS.md.
Quick Start
bash
# Build the Solidity compiler if not already built:
cargo build --release --bin neo-solc
# Install nccs if needed:
dotnet tool install -g neo.compiler.csharp
# Provide a funded TestNet wallet WIF and run:
NEO_TESTNET_WIF=<your-wif> node scripts/standards_mirror_testnet.jsThe runner is idempotent — already-deployed contracts are detected via the "Contract Already Exists" error and reused for subsequent assertion runs.
Structure
deployments/
├── manifest.json ← list of pairs + per-pair test cases
├── results.json ← machine-readable last-run output
├── RESULTS.md ← human summary
├── erc-20/
│ ├── solidity/DemoToken.sol (compiles via neo-solc)
│ └── csharp/DemoToken.{cs,csproj} (compiles via nccs)
├── erc-721/
│ ├── solidity/DemoNFT.sol
│ └── csharp/DemoNFT.{cs,csproj}
├── erc-2981/
│ ├── solidity/RoyaltyNFT.sol
│ └── csharp/RoyaltyNFT.{cs,csproj}
└── erc-3525/
├── solidity/Bond.sol
└── csharp/Bond.{cs,csproj}Adding More Pairs
- Create a new
<standard-id>/solidity/Contract.soland<standard-id>/csharp/Contract.{cs,csproj}. - Append a pair entry to
manifest.jsonwith the test invocation matrix. - Re-run the script. New deploys will pick up; existing ones are reused.
Compatibility Notes
A few neo-solc 0.18 quirks surfaced during this work; we document them so future contract authors avoid them:
emit Event(...)faults during deploy. When the event signature's keccak256 starts with byte0xDD(e.g.Transfer(address,address,uint256)), the runtime trips a UTF-8 decoder error. Workaround: avoidemitin_deploy-reached code paths. The C# implementations don't have this issue.uint256(uint8 var)cast in constructor faults at deploy. Use a literal pre-computed constant instead.msg.senderat constructor time is the ManagementContract, not the deploying user. Solidity owner-init patterns likedeployer = msg.senderwon't work at deploy. UseRuntime.checkWitness(...)from the devpack post-deploy instead.
