Nit is git for web3 digital asset and helps user to commit an asset's activities (chronicle) to blockchain. Please note, this repository is for nit open-source tools. If you are looking for accessing nit via API services, please visit here for more details.
To make digital assets trustworthy and traceable, Nit leverages web3 technologies and Git core concepts. Everyone can chronicle their assets by creating on-chain records so that we can productively debate, narrate, and analyse. All asset histories are written on chain and are searchable by asset CID. A sample transaction can be found here.
Case study
- A crypto-based dossier could help prove Russia committed war crimes, CNN
- Starling Lab and Hala Systems file Cryptographic Submission of Evidence of War Crimes in Ukraine to the International Criminal Court, CAGR
nit adopt similar design as git.
-
When there is an update to the asset, such as updating creator information or updating content itself to create a child asset, there should be a new commit attach the asset itself.
-
Every asset has a Tree file in IPFS to describe the property of the asset, including creator, creation time, license, etc. The asset tree CID is included in the on-chain message. Here is the example of the asset tree.
The db diagram can be found here. In this diagram, you will find tables of commit
and assetTree
with the explanation of each data field
yarn global add @numbersprotocol/nit
If it's your first time to run nit
, initialize Nit with default configuration:
nit init
and provide personal information. The details of the Nit configuration format is in the Configuration section below.
nit config -e
The default integrity register (smart contract) is running on Avalanche Fuji (Testnet) and will migrate to Numbers mainnet in the future. You need to get some testing tokens from the Fuji faucet for paying transaction fee.
Create a working directory for the targeting asset:
mkdir ~/temp && cd ~/temp
Create the Asset Tree of the targeting asset. Example:
nit add <asset-filepath> -m "First registration."
To access the file of the CID, you can use browser to open the URL: https://<cid>.ipfs.dweb.link
Double check the Commit information meets your expectation:
nit status
Register the Commit on blockchain:
nit commit -m "commit description"
You can check the Commit on blockchain by following the explorer URL returned by Nit.
nit log <asset-cid> --blocks
Example command of the mockup Asset
nit log aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --blocks
Commit block numbers and indices
Total Commit number: 74
Index: 0, Block number: 7236185
Index: 1, Block number: 7236445
...
Index: 71, Block number: 10849040
Index: 72, Block number: 10849133
Index: 73, Block number: 11040035
You can specify the starting and ending indices of block numbers:
nit log <asset-cid> --from-index 3 --to-index 5
You will get the Commits from the block numbers associated to index 3 & 4.
Example command of the mockup Asset
nit log aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --from-index 71 --to-index 73
Commits in block 71 & 72 (exclude block 73)
Total Commit number: 74
block number: 10849040
tx: 0x6d5902173255afe379cc4ae934a6c684ecfd865679286665622de3cf10eddcbe
{
"assetTreeCid": "bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq",
"assetTreeSha256": "ad7e154b74da6715d576c5ef7379e52c116729e4f39022b54313430094edb35c",
"assetTreeSignature": "0x9faf5c9d13b8d90a7a8e88aa6daf089ca89593c28dc241347c4756e83c2f1ea53ed1cb9e189f7ab81c81327527c97595f44ed71dda8e5d78ebe0dccfe9dd27081c",
"author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
"timestampCreated": 1655720482,
"action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
"actionResult": "https://bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq.ipfs.dweb.link",
"abstract": "Action action-initial-registration."
}
block number: 10849133
tx: 0xe383fdc0f4eaf44e8bde4737f33bcd45742dcb846f3beb890976793d7cc9358e
{
"assetTreeCid": "bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu",
"assetTreeSha256": "6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d",
"assetTreeSignature": "0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b",
"author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
"timestampCreated": 1655720763,
"action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
"actionResult": "https://bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu.ipfs.dweb.link",
"abstract": "Action action-initial-registration."
}
nit diff <asset-cid> --from-index 3 --to-index 5
Example command of the mockup Asset
nit diff aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --from-index 71 --to-index 73
Diff of Commits and Asset Trees in block 71 & 72 (exclude block 73)
from: block 10849040, tx 0x6d5902173255afe379cc4ae934a6c684ecfd865679286665622de3cf10eddcbe
to: block 10849133, tx 0xe383fdc0f4eaf44e8bde4737f33bcd45742dcb846f3beb890976793d7cc9358e
Commit difference
{
"abstract": "Action action-initial-registration.",
"action": "bafkreiavifzn7ntlb6p2lr55k3oezo6pofwvknecukc5auhng4miowcte4",
-"actionResult": "https://bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq.ipfs.dweb.link",
-"assetTreeCid": "bafkreifnpykuw5g2m4k5k5wf55zxtzjmcftstzhtsarlkqytimajj3ntlq",
-"assetTreeSha256": "ad7e154b74da6715d576c5ef7379e52c116729e4f39022b54313430094edb35c",
-"assetTreeSignature": "0x9faf5c9d13b8d90a7a8e88aa6daf089ca89593c28dc241347c4756e83c2f1ea53ed1cb9e189f7ab81c81327527c97595f44ed71dda8e5d78ebe0dccfe9dd27081c",
+"actionResult": "https://bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu.ipfs.dweb.link",
+"assetTreeCid": "bafkreidptwydheqfybug4mmnzwzdg4rqxjvg4akl2pwjmrfxhqz33qv4tu",
+"assetTreeSha256": "6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d",
+"assetTreeSignature": "0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b",
"author": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"committer": "bafkreigzixvzu2tbxbvmvwcvlz2zwoagmb6c2q5egaq4lmd5sesyopmmx4",
"provider": "bafkreigtmno2wacf4ldb6ewbkboe7oojedsp3dky35djytor6guwzhbdpa",
-"timestampCreated": 1655720482
+"timestampCreated": 1655720763
}
Asset Tree difference
{
"abstract": "",
"assetCid": "bafybeif3ctgbmiso4oykvwj6jebyrkjxqr26bfrkesla5yr2ypgx47wgle",
"assetCreator": null,
"assetSha256": null,
"assetTimestampCreated": null,
"assetTreeCustomKey1": "foo",
"assetTreeCustomKey2": "bar",
"encodingFormat": "application/zip",
"license": {
"document": "https://starlinglab.org",
"name": "Starling License"
},
+"nftRecord": "bafkreielfjf7sfxigb4r7tejt7jhl6kthxoujwziywixlwxjjho32may7y"
}
The Nit configuration mimics the Hardhat configuration with additional fields.
The Nit configuration is at ~/.nitconfig.json
. Linux users can open the default editor by the command below:
nit config -e
Example of a Nit configuration:
{
// CID of the author's profile of original Assets
"author": "bafkreihkrnjvjeijjhalozcfpgrgb46673dlt4e3qm5bmvzzb4if423wse",
// CID of the committer's profile who creates Asset Trees and Commits
"committer": "bafkreihkrnjvjeijjhalozcfpgrgb46673dlt4e3qm5bmvzzb4if423wse",
// CID of the service provider who hosts the integrity registration service
"provider": "bafkreido4zu743f6isb5wninfkedvbirj2ngb5fkivrpdijh2xtd3s6rnu",
"defaultNetwork": "fuji",
"network": {
"rinkeby": {
"url": "https://eth-rinkeby.alchemyapi.io/v2/UO5kfog_UDJgGCuqeaSJmnE95_gKOnFN",
"gasLimit": 200000,
"accounts": [
"<private-key>",
],
// integrity record contract address
"contract": "0x2Aa4e29872DE77E1Bc6cF310d647F9cB0f9a073B",
"explorerBaseUrl": "https://rinkeby.etherscan.io/tx"
},
"avalanche": {
"chainId": 43114,
"url": "https://api.avax.network/ext/bc/C/rpc",
"accounts": [
"<private-key>",
],
"contract": "0x1970aFD0831E9233667fb9484910926c2b18BCb4",
"explorerBaseUrl": "https://snowtrace.io/tx"
},
"fuji": {
"url": "https://api.avax-test.network/ext/bc/C/rpc",
"chainId": 43113,
"gasLimit": 200000,
"accounts": [
"<private-key>",
],
"contract": "0xA2De03bee39Fa637440909abC5621063bC5DA926",
"explorerBaseUrl": "https://testnet.snowtrace.io/tx"
},
"polygon": {
"url": "https://polygon-rpc.com/",
"gasPrice": 60000000000,
"accounts": [
"<private-key>",
],
"contract": "0x2094747c6c870f20E38f701116CBb46845b5E5c1",
"explorerBaseUrl": "https://polygonscan.com/tx"
},
"moonbase": {
"url": "https://rpc.api.moonbase.moonbeam.network",
"accounts": [
"<private-key>",
],
"contract": "0xfbeA33fe2b266697404Dc5D1dC0A4ee9D0eDED23",
"explorerBaseUrl": "https://moonbase.moonscan.io/tx"
},
"aurora_testnet": {
"url": "https://testnet.aurora.dev/",
"chainId": 1313161555,
"accounts": [
"<private-key>",
],
"contract": "0x8e1bF90681C672e25aE880767d57f0552f6F5Cd1",
"explorerBaseUrl": "https://testnet.aurorascan.dev/tx"
}
},
// For the ipfsadd command. We will support web3.storage soon
"infura": {
"projectId": "aaaaaaaaaaaaaaaaaaaaaaaaaaa",
"projectSecret": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
Verify the integrity of an Asset Tree
nit verify --integrity-hash <assetTreeSha256> --signature <assetTreeSignature>
Example
nit verify --integrity-hash 6f9db0339205c0686e318dcdb2337230ba6a6e014bd3ec9644b73c33bdc2bc9d --signature 0xef547e124a9904dbdb5a418022ad03c621201b74111a3b4c5fac61b1d82350170766cef8a27737d21ca9b1bd4e04f7cdea460706b68b14e0ed17f2a3de83f9131b
Verification result
Signer address: 0x63B7076FC0A914Af543C2e5c201df6C29FCC18c5
If the signer address is different from the Committer's wallet address, you can treat this Commit as not trustworthy.