forked from hiero-ledger/hiero-sdk-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-stateful-contract.js
151 lines (129 loc) · 5.83 KB
/
create-stateful-contract.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
require("dotenv").config();
const {
Client,
PrivateKey,
ContractCreateTransaction,
ContractExecuteTransaction,
FileCreateTransaction,
ContractFunctionParameters,
ContractCallQuery,
Hbar,
AccountId,
} = require("@hashgraph/sdk");
// Import the compiled contract
const helloWorld = require("./stateful.json");
async function main() {
let client;
try {
client = Client.forName(process.env.HEDERA_NETWORK).setOperator(
AccountId.fromString(process.env.OPERATOR_ID),
PrivateKey.fromString(process.env.OPERATOR_KEY)
);
} catch {
throw new Error(
"Environment variables HEDERA_NETWORK, OPERATOR_ID, and OPERATOR_KEY are required."
);
}
// The contract bytecode is located on the `object` field
const contractByteCode = helloWorld.object;
// Create a file on Hedera which contains the contact bytecode.
// Note: The contract bytecode **must** be hex encoded, it should not
// be the actual data the hex represents
const fileTransactionResponse = await new FileCreateTransaction()
.setKeys([client.operatorPublicKey])
.setContents(contractByteCode)
.execute(client);
// Fetch the receipt for transaction that created the file
const fileReceipt = await fileTransactionResponse.getReceipt(client);
// The file ID is located on the transaction receipt
const fileId = fileReceipt.fileId;
console.log(`contract bytecode file: ${fileId}`);
// Create the contract
const contractTransactionResponse = await new ContractCreateTransaction()
// Set the parameters that should be passed to the contract constructor
// In this case we are passing in a string with the value "hello from hedera!"
// as the only parameter that is passed to the contract
.setConstructorParameters(
new ContractFunctionParameters()
.addString("hello from hedera!"))
// Set gas to create the contract
.setGas(100000000)
// The contract bytecode must be set to the file ID containing the contract bytecode
.setBytecodeFileId(fileId)
// Set the admin key on the contract in case the contract should be deleted or
// updated in the future
.setAdminKey(client.operatorPublicKey)
.execute(client);
// Fetch the receipt for the transaction that created the contract
const contractReceipt = await contractTransactionResponse.getReceipt(client);
// The conract ID is located on the transaction receipt
const contractId = contractReceipt.contractId;
console.log(`new contract ID: ${contractId}`);
// Call a method on a contract that exists on Hedera
// Note: `ContractCallQuery` cannot mutate a contract, it will only return the last state
// of the contract
const contractCallResult = await new ContractCallQuery()
// Set the gas to execute a contract call
.setGas(75000)
// Set which contract
.setContractId(contractId)
// Set the function to call on the contract
.setFunction("get_message")
.setQueryPayment(new Hbar(1))
.execute(client);
// Check if an error was returned
if (contractCallResult.errorMessage != null && contractCallResult.errorMessage != "") {
console.log(`error calling contract: ${contractCallResult.errorMessage}`);
}
// Get the message from the result
// The `0` is the index to fetch a particular type from
//
// e.g.
// If the return type of `get_message` was `(string[], uint32, string)`
// then you'd need to get each field separately using:
// const stringArray = contractCallResult.getStringArray(0);
// const uint32 = contractCallResult.getUint32(1);
// const string = contractCallResult.getString(2);
const message = contractCallResult.getString(0);
console.log(`contract message: ${message}`);
// Call a method on a contract exists on Hedera, but is allowed to mutate the contract state
const contractExecTransactionResponse = await new ContractExecuteTransaction()
// Set which contract
.setContractId(contractId)
// Set the gas to execute the contract call
.setGas(100000000)
// Set the function to call and the parameters to send
// in this case we're calling function "set_message" with a single
// string paramater of value "hello from hedera again!"
// If instead the "set_message" method were to require "string[], uint32, string"
// parameters then you must do:
// new ContractFunctionParameters()
// .addStringArray(["string 1", "string 2"])
// .addUint32(1)
// .addString("string 3")
.setFunction("set_message", new ContractFunctionParameters()
.addString("hello from hedera again!"))
.execute(client);
await contractExecTransactionResponse.getReceipt(client);
// Call a method on a contract that exists on Hedera
const contractUpdateResult = await new ContractCallQuery()
// Set which contract
.setContractId(contractId)
// Set gas to use
.setGas(100000000)
// Set the function to call on the contract
.setFunction("get_message")
// Set the query payment explicitly since sometimes automatic payment calculated
// is too low
.setQueryPayment(new Hbar(3))
.execute(client);
// Check if there were any errors
if (contractUpdateResult.errorMessage != null && contractUpdateResult.errorMessage != "") {
console.log(`error calling contract: ${contractUpdateResult.errorMessage}`);
return;
}
// Get a string from the result at index 0
const message2 = contractUpdateResult.getString(0);
console.log(`contract returned message: ${message2}`);
}
void main();