{
  "slug": "Make-Crowdfunding-Smart-Contract-using-Solidity-and-Golang-Language-bd5dc7c8f84f",
  "title": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
  "subtitle": "We want to make smart contracts to solve a real problem in the real world.\nImagine a group of people who want to contribute their money to…",
  "excerpt": "We want to make smart contracts to solve a real problem in the real world.\nImagine a group of people who want to contribute their money to…",
  "date": "2023-12-27",
  "tags": [
    "Go"
  ],
  "readingTime": "10 min",
  "url": "https://medium.com/@mobinshaterian/make-crowdfunding-smart-contract-using-solidity-and-golang-language-bd5dc7c8f84f",
  "hero": "https://cdn-images-1.medium.com/max/800/1*KU7VLgI009OXS4bfflHmaQ.png",
  "content": [
    {
      "type": "heading",
      "level": 2,
      "text": "Make Crowdfunding Smart Contract using Solidity and Golang Language"
    },
    {
      "type": "paragraph",
      "html": "We want to make smart contracts to solve a real problem in the real world.<br>Imagine a group of people who want to contribute their money to a specific project. And when we gather the money the owner wants to spend this money on a special vendor. Also, it is necessary to vote and select a vendor by the contributor. We want to guarantee that everything executes without any cheat. The best solution is using smart contracts to keep every thing immutable."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*KU7VLgI009OXS4bfflHmaQ.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 516,
      "height": 462
    },
    {
      "type": "paragraph",
      "html": "It also can be used in many diffrent topics, such as gathering tax, managment of building,&nbsp;…&nbsp;."
    },
    {
      "type": "paragraph",
      "html": "Spending request attempts to withdraw money from the contract and send it to an external address."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Struct Document in solidity"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Removal of Unused or Unsafe Features"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Mappings outside Storage"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "If a struct or array contains a mapping, it can only be used in storage. Previously, mapping members were silently skipped in memory, which is confusing and error-prone.",
        "Assignments to structs or arrays in storage does not work if they contain mappings. Previously, mappings were silently skipped during the copy operation, which is misleading and error-prone."
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Storage vs Memory in Solidity"
    },
    {
      "type": "paragraph",
      "html": "Storage and Memory keywords in Solidity are analogous to Computer’s hard drive and Computer’s RAM. Much like RAM, <strong>Memory</strong> in Solidity is a temporary place to store data whereas <strong>Storage</strong> holds data between function calls. The Solidity Smart Contract can use any amount of memory during the execution but once the execution stops, the Memory is completely wiped off for the next execution. Whereas Storage on the other hand is persistent, each execution of the Smart contract has access to the data previously stored on the storage area."
    },
    {
      "type": "paragraph",
      "html": "Every transaction on Ethereum Virtual Machine costs us some amount of Gas. The lower the Gas consumption the better is your Solidity code. The Gas consumption of Memory is not very significant as compared to the gas consumption of Storage. Therefore, it is always better to use Memory for intermediate calculations and store the final result in Storage."
    },
    {
      "type": "list",
      "ordered": true,
      "items": [
        "State variables and Local Variables of structs, array are always stored in storage by default.",
        "Function arguments are in memory.",
        "Whenever a new instance of an array is created using the keyword ‘memory’, a new copy of that variable is created. Changing the array value of the new instance does not affect the original array."
      ]
    },
    {
      "type": "quote",
      "html": "Mapping key didn’t store in In smart contract we only have a value in smart contract."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Race condition in Smart contract"
    },
    {
      "type": "paragraph",
      "html": "All transactions in Ethereum are run serially. Just one after another. Everything your transaction does, including calling from one contract to another, happens within the context of your transaction and nothing else runs until your contract is done."
    },
    {
      "type": "paragraph",
      "html": "So race conditions are totally not a concern. You can call <code>balanceOf()</code> on another contract, put the result in a local variable, and use it with no worries that the balance in the other contract will change before you're done."
    },
    {
      "type": "paragraph",
      "html": "There are a few different ways to prevent race conditions in smart contracts. One common approach is to use locks, as described above. Another approach is to use a concept called <strong>timestamping</strong>. Timestamping involves assigning a timestamp to each transaction. Transactions are then processed in order of their timestamps, which helps to prevent conflicts."
    },
    {
      "type": "paragraph",
      "html": "In general, it is important to be aware of the potential for race conditions when writing smart contracts. There are a number of techniques that can be used to prevent race conditions, but it is important to choose the appropriate technique for the specific application."
    },
    {
      "type": "quote",
      "html": "Please pay attention to using iteration in smart contracts, It needs more gas to execute."
    },
    {
      "type": "quote",
      "html": "When we release a new deployment of smart contracts they have a different hash code and they are not related to each other."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Every web3 project follows these steps:"
    },
    {
      "type": "list",
      "ordered": true,
      "items": [
        "Write solidity and check it with <a href=\"https://remix.ethereum.org\" target=\"_blank\" rel=\"noreferrer noopener\">https://remix.ethereum.org</a>",
        "Compile solidity project into JSON and ABI",
        "Deploy compile file on a network",
        "Write tests for check functionality"
      ]
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*AGpYQWCefk7hqoJSNGSWLA.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 518,
      "height": 451
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Lets make it"
    },
    {
      "type": "paragraph",
      "html": "We have a manager and list of contributors, and minimum value of contribute."
    },
    {
      "type": "code",
      "lang": "solidity",
      "code": "// SPDX-License-Identifier: GPL-3.0-or-laterpragma solidity >=0.5.0 <0.9.0;\n// linter warnings (red underline) about pragma version can igonored!// contract code will go\nherecontract Campaing {\n  address public manager;\n  uint256 public minimumContribution;\n  mapping (address => bool) public approvers;\n  constructor(uint256 min) {\n    manager = msg.sender;\n    minimumContribution = min;\n  }\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*hfFz62NcC_EBczAp8Fyg9g.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 537,
      "height": 309
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*FpuajmosSizMuLQCvtDd9w.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 539,
      "height": 447
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Add contribute with minimum amount in contribute list"
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function contibute() public payable {\n  require(msg.value >= minimumContribution, \"minimum contribute is required.\");\n  approvers[msg.sender] = true;\n  approversCount ++;\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*IiwHr36OxkIpbPRbuz_BMA.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 545,
      "height": 497
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*RMSKbZq-cGUmzsBoWMF0vA.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 549,
      "height": 451
    },
    {
      "type": "quote",
      "html": "If the value is less than min we get an error and reduce the gas."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*1g2oB4F7bTuLqTOLFmHQQg.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 540,
      "height": 481
    },
    {
      "type": "heading",
      "level": 3,
      "text": "We can check whether the address is contributed or not:"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*3hikSzmRkcW5pDAI1fjjTQ.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 522,
      "height": 71
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function isPaied() public view returns (bool) {\n  return (approvers[msg.sender]);\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*6k-Ro9SdBQUm5hkhYVh4GQ.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 127,
      "height": 75
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Get balance of smart contract account"
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function getBalance() public view returns(uint256){\n  return (address(this).balance);\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*twqsMmPkB0iOdWsEsB2W8g.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 719,
      "height": 498
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Now, added a list of requests for each provider. Providers are addressed that the manager wants to spend money on contributors."
    },
    {
      "type": "code",
      "lang": "go",
      "code": "struct Request {        string description;        uint256 value;        address payable recipient;\nbool complete;        uint256 approvalCount;        mapping(address => bool) approvals;    }"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "the manager only can call these function so we need make modifier for them."
    },
    {
      "type": "code",
      "lang": "solidity",
      "code": "modifier onlyManager() {        require(            msg.sender == manager,\n\"Only the campaign manager can call this function.\"        );        _;    }"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "add request is a function that the manager can make it and create a new provider for spending the contributors"
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function addRequest(string memory description, uint256 value, address payable recipient) public\nonlyManager {\n  Request storage req = requests[numRequests++];\n  req.description = description;\n  req.value = value;\n  req.recipient = recipient;\n  req.complete = false;\n  req.approvalCount = 0;\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*yloaIFC4NkwSVp4wvccJ1g.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 690,
      "height": 723
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*SCZ0ABRFzQhpq7ymWAPxew.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 729,
      "height": 506
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function approveRequest(uint256 index) public{\n  Request storage req = requests[index];\n  require(approvers[msg.sender], \"Only contributors can approve a specific payment request\");\n  require(!req.approvals[msg.sender], \"You have already voted to approve this request\");\n  require(index < numRequests, \"You can vote only in valid index. more than valid value\");\n  require(index >= 0, \"You can vote only in valid index. minus value\");\n  req.approvals[msg.sender] = true;\n  req.approvalCount++;\n}"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "\"water\",1000,0xdD870fA1b7C4700F2BD7f44238821C26f7392148"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Test of this part needs three different accounts : manager, contributor, provider"
    },
    {
      "type": "list",
      "ordered": true,
      "items": [
        "manager&nbsp;: deploy contract",
        "contributor: contribute inside the system",
        "manager: create a request for provider",
        "contributor: approve the request"
      ]
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*JpJSkEnXnuwGI66ZsNmgcw.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 627,
      "height": 509
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*ZhF512DSh48OJVwPRWK-MQ.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 614,
      "height": 397
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Manager can finalize Request and send money to provider"
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "function finalizeRequest(uint256 index) public onlyManager {\n  require(index < numRequests, \"You can vote only in valid index. more than valid\");\n  require(index >= 0, \"You can vote only in valid index. minus value\");\n  Request storage req = requests[index];\n  require(!req.complete, \"This request has been completed.\");\n  req.recipient.transfer(req.value);\n  req.complete = true;\n}"
    },
    {
      "type": "paragraph",
      "html": "Also we need to check the number of votes that send to the request:"
    },
    {
      "type": "code",
      "lang": "solidity",
      "code": "require(            req.approvalCount > (approversCount / 2),\n\"This request needs more approvals before it can be finalized\"        );"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*BXRAepm4zjbRTAbk1Oqo_A.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 623,
      "height": 593
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*NnQDt7ANQIIdbh_rRYe9IA.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 613,
      "height": 395
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*CUHx1gegvdHvM6wjgS_Xxw.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 689,
      "height": 513
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Final code is exist in my repository:"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Deploy Solidity code with Go Ethereum:"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Connect to network"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type Client struct {\n    Client *ethclient.Client\n}\nfunc (c *Client) NewClient(address string) {\n    client, err := ethclient.Dial(address) if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(\"connect to network ...\") c.Client = client\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Using Ganache"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "ganache-cli"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Define Accounts"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*9zhQAE5bvb6xS-cYVLJx-w.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 638,
      "height": 478
    },
    {
      "type": "paragraph",
      "html": "Put three account in env file"
    },
    {
      "type": "code",
      "lang": "properties",
      "code": "ADDRESS = http://localhost:8545MANAGER_ADDRESS =\n0xBad21545CDAc5eA56050a5441E435B2437fE4770MANAGER_PRIVATE_ADDRESS =\n0xbcab03c0fb40ccdd5d75b8024731dd772113b02d01132d81c584027d8a7280b9PROVIDER_ADDRESS =\n0xEc89A6a668206286a875BB906B79BbB756f09E22PROVIDER_PRIVATE_ADDRESS =\n0xbf6e3ba07b0ea7a98e5cbd0f0206bcdb35fd9520571c28cc16c803cae702dc89CONTRIBUTOR_ADDRESS =\n0x6BC477cE822a30331D0D5Ce4B5CeA23b2f2eEaEbCONTRIBUTOR_PRIVATE_ADDRESS =\n0x2b7b6e43aca333d79375eb8cb3d225b795480596d4fff6e0abf70c111628a410"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Get balance of accounts"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type Account struct {\n    PublicAddress common.Address\n    PrivateAddress string\n    Name string\n    client *ethclient.Client\n}\n// NewAccount creates a new instance of Account\nfunc NewAccount(publicAddress string, privateAddress string, client *client.Client) *Account {\n    return &Account{\n        PublicAddress: common.HexToAddress(publicAddress), client: client.Client,\n    }\n}\nfunc (a *Account) GetBalance() *big.Int {\n    balance, err := a.client.BalanceAt(context.Background(), a.PublicAddress, nil) if err != nil {\n        log.Fatal(err)\n    }\n    return balance\n}"
    },
    {
      "type": "paragraph",
      "html": "Result:"
    },
    {
      "type": "code",
      "lang": "bash",
      "code": "go run *.goconnect to network ...balance manager : 1000000000000000000000balance provider :\n1000000000000000000000contributor manager : 1000000000000000000000"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Install Abigen:"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "$ cd $GOPATH/src/github.com/ethereum/go-ethereum$ go build ./cmd/abigen"
    },
    {
      "type": "paragraph",
      "html": "build&nbsp;.sol"
    },
    {
      "type": "code",
      "lang": "bash",
      "code": "cd contracts/solc --abi Campaign.sol -o buildsolc --bin Campaign.sol -o Campaign.bin"
    },
    {
      "type": "paragraph",
      "html": "Then abigen can be run again, this time passing Campaign.bin:"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "abigen --abi ./build/Campaign.abi --pkg main --type Campaign --out Campaign.go --bin\n./Campaign.bin/Campaign.bin"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "If the code does not deploy on network:"
    },
    {
      "type": "paragraph",
      "html": "or got below error&nbsp;:"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "vm exception while processing transaction: invalid opcode errorinvalid opcode error in ganache 2.7.1"
    },
    {
      "type": "code",
      "lang": "bash",
      "code": "pip3 install solc-select"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "solc-select use <version> --always-install"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "solc --versionsolc, the solidity compiler commandline interfaceVersion:\n0.8.7+commit.e28d00a7.Linux.g++"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Deploy on network with manger account:"
    },
    {
      "type": "paragraph",
      "html": "First we need get private key from the account"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(privateAddress, \"0x\")) if err != nil {\nlog.Fatal(err) }"
    },
    {
      "type": "paragraph",
      "html": "// HexToECDSA parses a secp256k1 private key."
    },
    {
      "type": "heading",
      "level": 3,
      "text": "Deploy function"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type Campaign struct {\n    instance *contracts.Campaign\n    txAddress common.Address\n    tx *types.Transaction\n    Min *big.Int\n    client *ethclient.Client\n}\nfunc NewCampaign(min *big.Int, client *ethclient.Client) *Campaign {\n    return &Campaign{\n        Min:\n        min, client: client,\n    }\n}\nfunc (c *Campaign) Deploy(manager *account.Account) {\n    nonce := manager.GetNonce() gasPrice, err := c.client.SuggestGasPrice(context.Background()) if\n    err != nil {\n        log.Fatal(err)\n    }\n    chainID, err := c.client.ChainID(context.Background()) if err != nil {\n        log.Fatal(err)\n    }\n    auth, err := bind.NewKeyedTransactorWithChainID(manager.PrivateKey, chainID) if err != nil {\n        fmt.Println(err)\n    }\n    auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) // in wei auth.GasLimit =\n    uint64(300000) // in units auth.GasPrice = gasPrice txAddress, tx, instance, err :=\n    contracts.DeployCampaign(auth, c.client, c.Min) if err != nil {\n        fmt.Println(\"DeployLottery\") log.Fatal(err.Error())\n    }\n    c.instance = instance c.txAddress = txAddress c.tx = tx fmt.Println(txAddress.Hex())\n    fmt.Println(tx.Hash().Hex())\n}"
    },
    {
      "type": "paragraph",
      "html": "Run"
    },
    {
      "type": "code",
      "lang": "bash",
      "code": "go run *.goconnect to network ...balance manager : 999999400000000000000balance provider :\n1000000000000000000000contributor manager : 1000000000000000000000nonce manager :  1deploying\ncontract  ...\n_____________________0x8195b8a7757977AA6ae6Df873dA452a65Ab4791F0x1e75f1dfa1a7454599acce94e4e1ccfeaa4d9633e0e11ec75cc896c0981e77bbbalance manager : 999998800000000000000"
    },
    {
      "type": "paragraph",
      "html": "Terminal"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "Transaction: 0x1e75f1dfa1a7454599acce94e4e1ccfeaa4d9633e0e11ec75cc896c0981e77bb  Contract created:\n0x8195b8a7757977aa6ae6df873da452a65ab4791f  Gas usage: 300000  Block number: 2  Block time: Wed Dec\n27 2023 16:40:48 GMT  Runtime error: code size to deposit exceeds maximum code size"
    },
    {
      "type": "paragraph",
      "html": "Now we deploy our contract on Ganache network."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Get Information from the block"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (a *Account) GetHeader() *big.Int {\n    header, err := a.client.HeaderByNumber(context.Background(), nil) if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(header.Number.String()) // 5671744\n    return header.Number\n}\nfunc (a *Account) GetDataFromBlock(blockNumber *big.Int) {\n    block, err := a.client.BlockByNumber(context.Background(), blockNumber) if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(\"block.Number().Uint64() \", block.Number().Uint64()) // 5671744\n    fmt.Println(\"block.Time()\", block.Time()) // 1527211625\n    fmt.Println(\"block.Difficulty().Uint64()\", block.Difficulty().Uint64()) // 3217000136609065\n    fmt.Println(\"block.Hash().Hex()\", block.Hash().Hex()) //\n    0x9e8751ebb5069389b855bba72d94902cc385042661498a415979b7b6ee9ba4b9\n    fmt.Println(\"len(block.Transactions())\", len(block.Transactions())) // 144\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "One time deploy and then only use the contract transaction"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "my := common.HexToAddress(\"0xdd3f3c8afb70786e3bfb7a8cd8d44a3c5049268e\") var err error\ncampaign.Instance, err = contracts.NewCampaign(my, client.Client) if err != nil {  fmt.Println(err)\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Contribute on network"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) Contribute(contributor *account.Account) {\n    nonce := contributor.GetNonce() gasPrice, err := c.client.SuggestGasPrice(context.Background())\n    if err != nil {\n        log.Fatal(err)\n    }\n    chainID, err := c.client.ChainID(context.Background()) if err != nil {\n        log.Fatal(err)\n    }\n    auth, err := bind.NewKeyedTransactorWithChainID(contributor.PrivateKey, chainID) if err != nil {\n        log.Fatal(err)\n    }\n    auth.Nonce = big.NewInt(int64(nonce)) auth.Value = c.Min // in wei auth.GasLimit =\n    uint64(3000000) // in units auth.GasPrice = gasPrice tx, err := c.instance.Contribute(auth) if\n    err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(\"transaction hash\") fmt.Println(tx.Hash())\n}"
    },
    {
      "type": "code",
      "lang": "bash",
      "code": "go run *.goconnect to network ...block.Number().Uint64()  21block.Time()\n1703691148block.Difficulty().Uint64() 0block.Hash().Hex()\n0x06c93b2954bed6bd1f76340b4b504c985293abbff6b21006dc359daf0d65198clen(block.Transactions())\n1>>>>>>>>>>>>>>>>>>>>>>Balance>>>>>>>>>>>>>>>>balance manager : 999992200000000000000balance\nprovider : 1000000000000000000000balance contributor :\n999999662975999994800<<<<<<<<<<<<<<<<<<<<<<Balance<<<<<<<<<<<<<<<<<deploying contract  ...\n0xaf9087a308a23E335Dd8bB73E5b77AD0bF625Cd00xd56b10c190f65cec3be4f437f22da9fce4f3149d770b65fb494ca5f79af70d48>>>>>>>>>>>>>>>>>>>>>>Balance>>>>>>>>>>>>>>>>balance manager : 999991600000000000000balance provider : 1000000000000000000000balance contributor : 999999662975999994800<<<<<<<<<<<<<<<<<<<<<<Balance<<<<<<<<<<<<<<<<<contribute ...transaction hash ...0xfc2028dbaa4235e4a19a0b2e437db48b8cdbb6e05f0bebdd93eda4209e0541c6>>>>>>>>>>>>>>>>>>>>>>Balance>>>>>>>>>>>>>>>>balance manager : 999991600000000000000balance provider : 1000000000000000000000balance contributor : 999999620847999993800<<<<<<<<<<<<<<<<<<<<<<Balance<<<<<<<<<<<<<<<<<"
    },
    {
      "type": "paragraph",
      "html": "Console result:"
    },
    {
      "type": "paragraph",
      "html": "deploy"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "Transaction: 0xd56b10c190f65cec3be4f437f22da9fce4f3149d770b65fb494ca5f79af70d48  Contract created:\n0xaf9087a308a23e335dd8bb73e5b77ad0bf625cd0  Gas usage: 300000  Block number: 22"
    },
    {
      "type": "paragraph",
      "html": "contribute"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "Transaction: 0xfc2028dbaa4235e4a19a0b2e437db48b8cdbb6e05f0bebdd93eda4209e0541c6  Gas usage: 21064\nBlock number: 23"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*PTXLyNb25KGw7QRJWnsx-Q.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 1238,
      "height": 269
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Call Is paid function"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) IsPaid(contributor *account.Account) bool {\n    result, err := c.Instance.IsPaid(&bind.CallOpts{\n        From:\n        contributor.PublicAddress, Context: context.Background(),\n    }) if err != nil {\n        fmt.Println(\"IsPaid\") fmt.Println(err)\n    }\n    fmt.Println(result) return result\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Call Get balance function"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) GetBalance() *big.Int {\n    result, err := c.Instance.GetBalance(nil) if err != nil {\n        fmt.Println(\"IsPaid\") fmt.Println(err)\n    }\n    fmt.Println(result) return result\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Add request"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) AddRequest(request entity.Request, manager *account.Account) {\n    nonce := manager.GetNonce() gasPrice, err := c.client.SuggestGasPrice(context.Background()) if\n    err != nil {\n        log.Fatal(err)\n    }\n    auth, err := bind.NewKeyedTransactorWithChainID(manager.PrivateKey, c.chainID) if err != nil {\n        log.Fatal(err)\n    }\n    auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) // in wei auth.GasLimit =\n    uint64(6721975) // in units 6721975 auth.GasPrice = gasPrice tx, err :=\n    c.Instance.AddRequest(auth, request.Description, request.Value, request.ProviderAddress) if err\n    != nil {\n        fmt.Println(\"CreateRequest\") fmt.Println(err.Error()) log.Fatal(err)\n    }\n    fmt.Println(\"transaction hash ...\") fmt.Println(tx.Hash())\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*X_pDWvB7UhmETqWlmwEzXA.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 1228,
      "height": 415
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Function get number of requests"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) GetNumberOfRequests() *big.Int {\n    result, err := c.Instance.NumRequests(nil) if err != nil {\n        fmt.Println(\"GetNumberOfRequests\") fmt.Println(err)\n    }\n    fmt.Println(result) return result\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Function Approve request"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) ApproveRequest(contributor *account.Account, index *big.Int) {\n    nonce := contributor.GetNonce() gasPrice, err := c.client.SuggestGasPrice(context.Background())\n    if err != nil {\n        log.Fatal(err)\n    }\n    auth, err := bind.NewKeyedTransactorWithChainID(contributor.PrivateKey, c.chainID) if err != nil\n    {\n        log.Fatal(err)\n    }\n    auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) // in wei auth.GasLimit =\n    uint64(6721975) // in units 6721975 auth.GasPrice = gasPrice tx, err :=\n    c.Instance.ApproveRequest(auth, index) if err != nil {\n        fmt.Println(\"ApproveRequest\") fmt.Println(err.Error()) log.Fatal(err)\n    }\n    fmt.Println(\"transaction hash ...\") fmt.Println(tx.Hash())\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*MDUr2Qnx2zn6t6h7Y1XZ7g.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 1581,
      "height": 568
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Function Finalize Request"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (c *Campaign) FinalizeRequest(manager *account.Account, index *big.Int) {\n    nonce := manager.GetNonce() gasPrice, err := c.client.SuggestGasPrice(context.Background()) if\n    err != nil {\n        log.Fatal(err)\n    }\n    auth, err := bind.NewKeyedTransactorWithChainID(manager.PrivateKey, c.chainID) if err != nil {\n        log.Fatal(err)\n    }\n    auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) // in wei auth.GasLimit =\n    uint64(6721975) // in units 6721975 auth.GasPrice = gasPrice tx, err :=\n    c.Instance.FinalizeRequest(auth, index) if err != nil {\n        fmt.Println(\"FinalizeRequest\") fmt.Println(err.Error()) log.Fatal(err)\n    }\n    fmt.Println(\"transaction hash ...\") fmt.Println(tx.Hash())\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*I-dG1Mp5lNFVySedPppYEQ.png",
      "alt": "Make Crowdfunding Smart Contract using Solidity and Golang Language",
      "caption": "",
      "width": 1581,
      "height": 713
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Final code"
    }
  ]
}
