Check our terms and conditions, privacy policies, and cookies policy.
Copyright 2024 © All rights Reserved. Designed by LACNet
Before deploying your smart contracts in the LACChain Networks, see this overview that explains the minor changes you will need to incorporate to them.
When blockchain development is carried out in Golang it is common to use Go-ethereum libraries. If that is your case, in the following guide we will explain the necessary changes and examples of how to deploy a contract and send a transaction using the Golang programming language to the LACChain node.
Have the version [email protected] equal to or higher, if you do not have it, please download it with the command:
> go get github.com/ethereum/go-ethereum
Go to the archive /go-ethereum/blob/master/ethclient/ethclient.go and add the following function:
func (ec *Client) SendTransactionLacchain(ctx context.Context, tx *types.Transaction) ([]byte, error) {
var hex hexutil.Bytes
data, err := tx.MarshalBinary()
if err != nil {
return nil, err
}
err = ec.c.CallContext(ctx, &hex, "eth_sendRawTransaction", hexutil.Encode(data))
if err != nil {
return nil, err
}
return hex, nil
}
This function will return the hash of the transaction, which is necessary to then obtain the receipt of the transaction.
To deploy a smart contract please create a new directory called deploy and a new file called deploy.go into this deploy directory. Now, copy the following example in deploy.go file:
package main
import (
"context"
"crypto/ecdsa"
"encoding/hex"
"fmt"
"log"
"math/big"
"time"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
“github.com/ethereum/go-ethereum/ethclient”
)
func main() {
client, err := lacnet.Dial(“”)
if err != nil {
log.Fatal(err)
}
privateKey, err := crypto.HexToECDSA("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3")
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
log.Fatal(err)
}
// arguments
addressArg, err := abi.NewType("address", "", nil)
if err != nil {
log.Fatal(err)
}
uint256Arg, err := abi.NewType("uint256", "", nil)
if err != nil {
log.Fatal(err)
}
// Encode LACChain parameters
lacchainAddress := common.HexToAddress(“
It is important to mention that two parameters are added, the nodeAddress and the time expiration, these two parameters are in the part of “//Encode LACChain parameters” in the previous code. These two parameters are necessary to send the transaction to the network.
After copying the code, consider changing the following values:
Now, compile the code with the following command:
> go build deploy.go
Run the executable to display the contract:
> ./deploy
If everything is correct, a contract will be displayed and the transaction hash will show you.
$ f90176820ca380830f42408080b90126608060405234801561001057600080fd5b5060c78061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80636057361d146037578063b05784b8146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050607e565b005b60686088565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea26469706673582212208595760c8d4272f1711ffb94441dddc78e22630630efc2bc60b984de1caeb06c64736f6c63430006030033000000000000000000000000d00e6624a73f88b39f82ab34e8bf2b4d226fd7680000000000000000000000000000000000000000000000000000000062cdebe31ba05c868ff63d72ab6df416c3817175de892119f2f3c76d6fc48a46b8e30ba2b270a020a3cf8e01be38ddecc2813187fc641816bb53e7f1115e7a44eb77c63ed0f6f8
tx sent: 0xaedf5b9c249100cc4c8139df856e065826742cc760a9b381fc179d128ec462c3
Contract address: 0xAfbb9195B995Ebee606AC453Fe717f2eE1041838
In this example we will send a transaction to the previously deployed contract, to change the value stored in the contract.
To deploy a smart contract please create new folder called send and a new file called main.go into this directory. Now copy the following example:
package main
import (
"context"
"crypto/ecdsa"
"encoding/hex"
"fmt"
"log"
"math/big"
"os"
"strings"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
lacnet "prueba.com/ethclient"
)
func main() {
contractDeployed := os.Args[1]
contractAddress := common.HexToAddress(contractDeployed)
client, err := lacnet.Dial(“”)
if err != nil {
log.Fatal(err)
}
privateKey, err := crypto.HexToECDSA("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3")
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
log.Fatal(err)
}
// arguments
addressArg, err := abi.NewType("address", "", nil)
if err != nil {
log.Fatal(err)
}
uint256Arg, err := abi.NewType("uint256", "", nil)
if err != nil {
log.Fatal(err)
}
// Encode LACChain parameters
lacchainAddress := common.HexToAddress(“PUT_YOUR_NODEADDRESS“) //Change this by your nodeAddress /lacchain/data/nodeAddress
lacchainExpiration := new(big.Int).SetInt64(time.Now().Add(time.Minute * time.Duration(20)).Unix())
argumentsLAC := abi.Arguments{
{Type: addressArg},
{Type: uint256Arg},
}
valueLAC, err := argumentsLAC.Pack(
lacchainAddress,
lacchainExpiration,
)
if err != nil {
log.Fatal(err)
}
value := big.NewInt(0) // in wei (0 eth)
gasLimit := uint64(1000000) // in units
gasPrice := big.NewInt(0) // in wei 0 gas price
json := `[{"inputs": [{"internalType": "uint256","name": "num","type": "uint256"}],"name": "store","outputs": [],"stateMutability": "nonpayable","type": "function"}]`
// method := NewMethod("", "", Constructor, "nonpayable", false, false, []Argument{{"a", Uint256, false}, {"b", Uint256, false}}, nil)
// Test from JSON
abiContract, err := abi.JSON(strings.NewReader(json))
if err != nil {
log.Fatal(err)
}
packed, err := abiContract.Pack("store", big.NewInt(30))
if err != nil {
log.Fatal(err)
}
data, _ := hexutil.Decode("0x" + hex.EncodeToString(packed) + hex.EncodeToString(valueLAC)) //Adding to additional parameters nodeAddress + expiration
tx := types.NewTx(&types.LegacyTx{
Nonce: nonce,
To: &contractAddress,
Value: value,
Gas: gasLimit,
GasPrice: gasPrice,
Data: data,
})
signedTx, err := types.SignTx(tx, types.FrontierSigner{}, privateKey)
if err != nil {
log.Fatal(err)
}
rawTxBytes, err := signedTx.MarshalBinary()
if err != nil {
log.Fatal(err)
}
rawTxHex := hex.EncodeToString(rawTxBytes)
fmt.Println(rawTxHex) // f86...772
rawTxRLPBytes, err := hex.DecodeString(rawTxHex)
txRLP := new(types.Transaction)
rlp.DecodeBytes(rawTxRLPBytes, &txRLP)
txHash, err := client.SendTransactionLacchain(context.Background(), txRLP)
if err != nil {
log.Fatal(err)
}
fmt.Printf("tx sent: 0x%s\n", hex.EncodeToString(txHash))
time.Sleep(7 * time.Second)
receipt, err := client.TransactionReceipt(context.Background(), common.BytesToHash(txHash))
if err != nil {
fmt.Printf("failed get transaction receipt")
}
fmt.Printf("Transaction status: %d\n", receipt.Status)
input, _ := hexutil.Decode("0xb05784b8")
msg := ethereum.CallMsg{To: &contractAddress, Data: input}
result, err := client.CallContract(context.Background(), msg, receipt.BlockNumber)
if err != nil {
fmt.Println("failed get value from smart contract", err)
}
resultArgument := abi.Arguments{
{Type: uint256Arg},
}
newValue, err := resultArgument.Unpack(
result,
)
if err != nil {
fmt.Println(err)
}
fmt.Printf("New value is:%s", newValue)
}
It is important to mention that two parameters are added, the nodeAddress and the time expiration, these two parameters are in the part of “//Encode LACChain parameters” in the previous code. These two parameters are necessary to send the transaction to the network.
After copying the code, consider changing the following values:
Now, compile the code with the following command:
> cd send
> go build sendTransaction.go
Run the executable to display the contract:
> ./sendTransaction
For example, for our previously deployed contract it would be:
> ./sendTransaction 0xAfbb9195B995Ebee606AC453Fe717f2eE1041838
If everything is correct, you will see the following lines in your console:
f8c7820cb080830f424094afbb9195b995ebee606ac453fe717f2ee104183880b8646057361d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000d00e6624a73f88b39f82ab34e8bf2b4d226fd7680000000000000000000000000000000000000000000000000000000062cdfff81ca075b5ddaa8d82f3657e0acb3534cbbba102ac962b8c7ce0bf66e9a0316aed02eea07553d5fb04ecf70a838110693a41b34a36ed800cc395786b90beff29bcffdfe5
tx sent: 0xafc31b1c79e71b2a7e4cc9632d66c6c63a3577a240848420877d34052797ec00
Transaction status: 1
New value is:[30]
Check our terms and conditions, privacy policies, and cookies policy.
Copyright 2024 © All rights Reserved. Designed by LACNet