Blockchain on Golang Part 6: Smart Contract Interaction (Read/Write)

Ajiyba Nesij Korkmaz
4 min readJan 14, 2024

Welcome to the last part of our series on Blockchain on Golang. In this installment, we will delve into the exciting realm of interacting with smart contracts deployed on the blockchain network. Specifically, we will explore how to read and write data to a smart contract using Go.

Smart contracts are self-executing contracts with the terms of the agreement directly written into code. They enable automation of complex processes on the blockchain, such as managing digital assets and executing predefined actions when specific conditions are met.

For this article, we will use a simple smart contract written in Solidity, the language of choice for Ethereum and many other blockchain platforms. This contract allows us to store and retrieve a numerical value.

pragma solidity ^0.8.9;

contract Storage {

uint256 value;

function store(uint256 number) public{
value = number;
}

function retrieve() public view returns (uint256){
return value;
}
}

The variable named “value,” of type uint256, represents the data we want to store.

The “store” function takes a parameter passed to it and assigns that value to the “value” variable. This effectively allows us to store the data.

On the other hand, the “retrieve” function is of type “view” and, when called, returns the current state of the “value” variable.

If you need information about how to compile and deploy smart contract you can read previous article.

Lets Coding

Step 1 : Utilizing the “InitNetwork,” “ImportWallet,” and “PrepareTransaction” functions

We utilize the “InitNetwork” function to connect to the blockchain network. The “ImportWallet” function serves the purpose of importing our crypto wallet. We use the “PrepareTransaction” function for interacting with smart contracts.

We can directly copy the functions prepared in the previous articles.

networkURL := "https://api.avax-test.network/ext/bc/C/rpc"
InitNetwork(networkURL)

walletPublicAddress, walletPrivateAddress := ImportWallet("653......fa") // Private Key Here
config := PrepareTransaction(walletPublicAddress, walletPrivateAddress)

Step 2: Establishing the Smart Contract Connection

We create an instance using the address of the previously deployed smart contract. This instance allows us to interact with the contract.

The “NewStorage” function establishes a connection to the contract at the provided address, of type common.Address

contractAddress := common.HexToAddress("0x0585C2794c545BE869b4f398fD1bFD62E16D86eb")

store, err := Storage.NewStorage(contractAddress, client)
if err != nil {
log.Fatalf("An error occurred while establishing a connection with the smart contract : %v", err)
}

Step 3: Sending Data to the Smart Contract

In this step, we send data to the smart contract. We achieve this by using the “store” instance we previously created. We call the “store” function within the contract and provide it with a “big.Int” parameter and the “config” obtained from the “PrepareTransaction” function. This allows us to store data in the contract.

 tx, err := store.Store(config, big.NewInt(23))
if err != nil {
log.Fatalf("An error occurred while writing data to smart contract : %v", err)
}
fmt.Println("Writing process transaction: ", tx.Hash().Hex())

Step 4: Retrieving Data from the Smart Contract

To retrieve data from the smart contract, we use the “store” instance to call the “Retrieve” function. We need to provide a parameter of type “CallOpts”. This allows us to retrieve data from the smart contract.

 callOpts := &bind.CallOpts{
Pending: true,
}
value, err := store.Retrieve(callOpts)
if err != nil {
log.Fatalf("An error occurred while reading data from smart contract : %v", err)
}
fmt.Println("Reading process result : ", value)

Full Code

func main() {
networkURL := "https://api.avax-test.network/ext/bc/C/rpc"
InitNetwork(networkURL)

walletPublicAddress, walletPrivateAddress := ImportWallet("653......fa") // Private Key Here
config := PrepareTransaction(walletPublicAddress, walletPrivateAddress)

contractAddress := common.HexToAddress("0x0585C2794c545BE869b4f398fD1bFD62E16D86eb")
store, err := Storage.NewStorage(contractAddress, client)
if err != nil {
log.Fatalf("An error occurred while establishing a connection with the smart contract : %v", err)
}

tx, err := store.Store(config, big.NewInt(23))
if err != nil {
log.Fatalf("An error occurred while writing data to smart contract : %v", err)
}
fmt.Println("Writing process transaction: ", tx.Hash().Hex())

callOpts := &bind.CallOpts{
Pending: true,
}
value, err := store.Retrieve(callOpts)
if err != nil {
log.Fatalf("An error occurred while reading data from smart contract : %v", err)
}
fmt.Println("Reading process result : ", value)
}

Output

Connected
Writing process transaction : 0x0d67d7cffbe7454690142b7de2bd745b5d2f02fb39f21487908cb656e6c088aa
Reading process result : 23

Conclusion

In conclusion, this article demonstrated how to interact with a smart contract deployed on the blockchain network using Go. We covered initializing the network, importing a wallet, preparing transactions, establishing contract connections, sending data to the contract, and retrieving data from it.

Happy coding and exploring the world of blockchain technology!

--

--