The capstone will build upon the knowledge you have gained in the course in order to build a decentralized housing product.
Make sure you have ganache / ganache-cli installed and running on port 8545.
Run npm install
to install all dependencies
Run tests for different contracts:
npx truffle test test/TestERC721Mintable.js
npx truffle test test/TestSquareVerifier.js
npx truffle test test/TestSolnSquareVerifier.js
Migrate Contracts to rinkeyby:
npx truffle migrate --network rinkeby
SolnSquareVerifier Contact: 0x7d634D75E1AC77b27053D587b9ACf9f7e478a50d
OpenSea Collection: https://testnets.opensea.io/collection/udacity-blockchain-capstone2
SolnSquareVerifier ABI:
[
{
inputs: [
{
internalType: "address",
name: "verifierAddress",
type: "address",
},
],
payable: false,
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "owner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "approved",
type: "address",
},
{
indexed: true,
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "owner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "operator",
type: "address",
},
{
indexed: false,
internalType: "bool",
name: "approved",
type: "bool",
},
],
name: "ApprovalForAll",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "triggeredBy",
type: "address",
},
],
name: "Paused",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "uint256",
name: "index",
type: "uint256",
},
{
indexed: false,
internalType: "address",
name: "owner",
type: "address",
},
],
name: "SolutionAdded",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: true,
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "triggeredBy",
type: "address",
},
],
name: "Unpaused",
type: "event",
},
{
constant: false,
inputs: [
{
internalType: "bytes32",
name: "_myid",
type: "bytes32",
},
{
internalType: "string",
name: "_result",
type: "string",
},
],
name: "__callback",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "bytes32",
name: "_myid",
type: "bytes32",
},
{
internalType: "string",
name: "_result",
type: "string",
},
{
internalType: "bytes",
name: "_proof",
type: "bytes",
},
],
name: "__callback",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "approve",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
],
name: "balanceOf",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "getApproved",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "getBaseTokenURI",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "getName",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "getOwner",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "getSymbol",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "address",
name: "operator",
type: "address",
},
],
name: "isApprovedForAll",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "mint",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "ownerOf",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "safeTransferFrom",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
{
internalType: "bytes",
name: "_data",
type: "bytes",
},
],
name: "safeTransferFrom",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "bool",
name: "approved",
type: "bool",
},
],
name: "setApprovalForAll",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "bool",
name: "paused",
type: "bool",
},
],
name: "setPaused",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "bytes4",
name: "interfaceId",
type: "bytes4",
},
],
name: "supportsInterface",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "uint256",
name: "index",
type: "uint256",
},
],
name: "tokenByIndex",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "uint256",
name: "index",
type: "uint256",
},
],
name: "tokenOfOwnerByIndex",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "tokenURI",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "transferFrom",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "newOwner",
type: "address",
},
],
name: "transferOwnership",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: true,
inputs: [],
name: "verifier",
outputs: [
{
internalType: "contract Verifier",
name: "",
type: "address",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "uint256",
name: "index",
type: "uint256",
},
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "bytes32",
name: "key",
type: "bytes32",
},
],
name: "addSolution",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
{
internalType: "uint256[2]",
name: "a",
type: "uint256[2]",
},
{
internalType: "uint256[2][2]",
name: "b",
type: "uint256[2][2]",
},
{
internalType: "uint256[2]",
name: "c",
type: "uint256[2]",
},
{
internalType: "uint256[2]",
name: "input",
type: "uint256[2]",
},
],
name: "mintNFT",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
];
- Remix - Solidity IDE
- Visual Studio Code
- Truffle Framework
- Ganache - One Click Blockchain
- Open Zeppelin
- Interactive zero knowledge 3-colorability demonstration
- Docker
- ZoKrates
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> block number: 10627780
> block timestamp: 1651822829
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.470645290993425972
> gas used: 226537 (0x374e9)
> gas price: 10.060427244 gwei
> value sent: 0 ETH
> total cost: 0.002279059006574028 ETH
-------------------------------------
> Total cost: 0.002279059006574028 ETH
2_deploy_contracts.js
=====================
Deploying 'Verifier'
--------------------
> block number: 10627782
> block timestamp: 1651822831
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.46219090383786742
> gas used: 967859 (0xec4b3)
> gas price: 8.303468939 gwei
> value sent: 0 ETH
> total cost: 0.008036587143831601 ETH
Deploying 'SolnSquareVerifier'
------------------------------
> block number: 10627783
> block timestamp: 1651822837
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.437700464247193516
> gas used: 3211927 (0x310297)
> gas price: 7.624843152 gwei
> value sent: 0 ETH
> total cost: 0.024490439590673904 ETH
-------------------------------------
> Total cost: 0.032527026734505505 ETH
Summary
=======
> Total deployments: 3
> Final cost: 0.034806085741079533 ETH
Starting migrations...
======================
> Network name: 'rinkeby'
> Network id: 4
> Block gas limit: 29970705 (0x1c95111)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0xd9fe5aa7ca9d59c85774640da010bf780d4ffc18647f2cac8962e96c5b08164b
> Blocks: 1 Seconds: 16
> contract address: 0x92e3E89C6a7323F06323C994c60C7DE486e6370F
> block number: 10627786
> block timestamp: 1651822857
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.470685315545375621
> gas used: 226537 (0x374e9)
> gas price: 9.883747267 gwei
> value sent: 0 ETH
> total cost: 0.002239034454624379 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.002239034454624379 ETH
2_deploy_contracts.js
=====================
Deploying 'Verifier'
--------------------
> transaction hash: 0xa3ca371a4d4ba3c4754e26cc5f82c961a6b471f271b8a0986ac16314f6abd6d1
> Blocks: 1 Seconds: 12
> contract address: 0xFB5704195130EeFC7db01F17F792D3A97c2b4FF9
> block number: 10627788
> block timestamp: 1651822887
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.460539897513546488
> gas used: 967859 (0xec4b3)
> gas price: 10.011120813 gwei
> value sent: 0 ETH
> total cost: 0.009689353378949367 ETH
Deploying 'SolnSquareVerifier'
------------------------------
> transaction hash: 0xf563afdef0d54ca7694f247cda9cd779d78d6f5d058460eb38e64d2f13b827fc
> Blocks: 1 Seconds: 8
> contract address: 0x7d634D75E1AC77b27053D587b9ACf9f7e478a50d
> block number: 10627789
> block timestamp: 1651822902
> account: 0x37411253fC18C820EE52eB679b0c91d9C603a83B
> balance: 0.428025959789675347
> gas used: 3211927 (0x310297)
> gas price: 10.122875683 gwei
> value sent: 0 ETH
> total cost: 0.032513937723871141 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.042203291102820508 ETH