eth-smart-contract-cli

command module
v0.0.0-...-f65dcff Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2023 License: Apache-2.0 Imports: 25 Imported by: 0

README

CLI tool to demonstrate how to deploy and interact with Solidity smart contract on Ethereum.

The main objective of the project is to store proof of existence of a media file on chain. As it is not feasible to store actual media files or documents on chain due to high cost associated with storage we can store file metadata on chain and use that to check file integrity later.

Functionality:

  • create Ethereum wallet
  • check balance of Ethereum wallet
  • deploy smart contract
  • show status of smart contract
  • add media metadata (proof) to smart contract
  • verify media metadata on chain

CLI commands are grouped as follows:

  • wallet
    • create
    • balance
  • contract
    • deploy
    • status
  • file
    • add
    • verify

Solidity Smart Contract.

You will find a contract in Store.sol file. It's a basic smart contract for adding and retrieving values from a map.
The bindings for Go were generated using Solidity compiler and abigen:

solc Store.sol --combined-json abi,bin | abigen --pkg=main --type=storage --out=store.go --combined-json - 

Smart contract mapping to store media metadata.

 mapping(bytes16 => mediaFile) private mediaFiles;

A map key in our case is a UUID.v5 which is generated deterministically based on the name of the file. We therefore assume that in our scenario media files we are handling have unique names. Map value is a simple object with a name, hash and a date.

struct mediaFile {
    bytes name;
    bytes32 hash;
    uint32 created;
}

Name is base64 encoded base file name.
The hash is a sha256 hashsum of the file.
Date represents when the file was processed.

The main functions of the contract are add and get.

function add(bytes16 key, bytes memory name, bytes32 hash, uint32 created) public onlyOwner {
    mediaFiles[key] = mediaFile(name, hash, created);
    mapSize++;
}

function get(bytes16 key) public view returns (bytes memory, bytes32, uint32) {
    mediaFile memory file = mediaFiles[key];
    return (file.name, file.hash, file.created);
}

The contract contains a single modifier to ensure that only a contract owner can invoke certain functions.

modifier onlyOwner {
    require(msg.sender == _owner, "only the owner can call this function");
    _;
}

It is possible to change owner of the contract by passing an address of a new owner.

function changeOwner(address newOwner) public onlyOwner {
    _owner = newOwner;
}

Requirements.

  1. To run CLI you can use your existing wallet and private key or use wallet create to create one.
  2. That wallet should have sufficient amount of funds to pay for fees when deploying a contract.
  3. Most commands require a node_url which is a URL of json-rpc node. You can use Infura and create API key for either a mainnet or testnet.

Important note.

It's critically important to securely store a private key generated by wallet create command. Ideally private key should be stored in a file or environment variable.

Future work.

  1. This CLI could be extended to upload a file to IPFS distributed storage or Cloud storage and file location URL could be stored in media metadata struct in Solidity.
  2. Change CLI to API and add a simple Web interface for adding/verifying files.

Examples.

set environment variables

export NODE_URL=https://sepolia.infura.io/v3/8af265c9b1264b30bc4d6820d99adc53

create a wallet

Only required if you don't already have an Ethereum wallet or want to create a new one just for testing. Remember that new wallet will have to be funded. Use Sepolia testnet and get some test coins from one of many online faucets available.

 % ./eth-smart-contract-cli wallet create
--------------------
wallet created:
--------------------
{
 "private_key_hex": "0x292b226995dc3dfb53ba0953f0bc717e221a9c8d9cb4f3ad5dfa5ef125b03860",
 "public_key_hex": "0x040dd7015c247d38a0fab03b79886650b08b86d9a563ef01a32a1c8bf56ecc326e1338d1d64b3f824b7b7e334a0fd123930632b2ef399a98e8c3bad67a55f46f0a",
 "address_hex": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f"
}
--------------------

set environment variables

export PRIVATE_KEY=292b226995dc3dfb53ba0953f0bc717e221a9c8d9cb4f3ad5dfa5ef125b03860

Once you create a wallet make sure you send some coins to it.

check wallet balance

 % ./eth-smart-contract-cli wallet balance --address=0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f 
--------------------
{
 "address_hex": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f",
 "balance": 10000000000000000
}
--------------------

deploy a contract

 % ./eth-smart-contract-cli contract deploy --address=0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f
--------------------
contract deployed:
--------------------
{
 "address": "0x967B1116887667c40c4776D43e6996e1749FFc6F",
 "tx_id": "0xb3d9aaa76f0a6a5bd74c4572d22a815833d3ac890d58da5f8051105608626452"
}
--------------------

check the status of a deployed contract

 % ./eth-smart-contract-cli contract status --address=0x967B1116887667c40c4776D43e6996e1749FFc6F
--------------------
contract status:
--------------------
{
 "address": "0x967B1116887667c40c4776D43e6996e1749FFc6F",
 "owner_address": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f"
}
--------------------

check the wallet balance again

 % ./eth-smart-contract-cli wallet balance --address=0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f --node_url=https://sepolia.infura.io/v3/8af265c9b1264b30bc4d6820d99adc53  
--------------------
{
 "address_hex": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f",
 "balance": 9999999951921447
}
--------------------

add media file

 % ./eth-smart-contract-cli file add --contract_address=0x967B1116887667c40c4776D43e6996e1749FFc6F --file=test.pdf --contract_owner=0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f
--------------------
proof of file added:
--------------------
{
 "uuid": "8c361a49-261f-5c65-9666-9d1ece5848af",
 "name": "test.pdf",
 "hashsum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
 "tx_id": "0x0a00f11bf566328a4f29bdb9a9813421561d9898479dbef31617556892094672",
 "created": "2023-10-01T13:00:10+01:00"
}
--------------------

check the balance

 % ./eth-smart-contract-cli wallet balance --address=0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f --node_url=https://sepolia.infura.io/v3/8af265c9b1264b30bc4d6820d99adc53      
--------------------
{
 "address_hex": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f",
 "balance": 9999999819633195
}
--------------------

check the status of a deployed contract

 % ./eth-smart-contract-cli contract status --address=0x967B1116887667c40c4776D43e6996e1749FFc6F                                                                              
--------------------
contract status:
--------------------
{
 "address": "0x967B1116887667c40c4776D43e6996e1749FFc6F",
 "owner_address": "0xE60CD0DEbe2259f1Ef105c1E8d0090C4b843481f",
 "proofs_stored": 1
}
--------------------

verify media file

 % ./eth-smart-contract-cli file verify --contract_address=0x967B1116887667c40c4776D43e6996e1749FFc6F --file=test.pdf                                                     
--------------------
verify file metadata:
--------------------
{
 "uuid": "8c361a49-261f-5c65-9666-9d1ece5848af",
 "name": "test.pdf",
 "hashsum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
--------------------
file metadata found on-chain:
--------------------
{
 "uuid": "8c361a49-261f-5c65-9666-9d1ece5848af",
 "name": "test.pdf",
 "hashsum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
 "created": "2023-10-01T13:00:10+01:00"
}
--------------------

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL