-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: mateuszm-arianelabs <mateusz.marcinkowski@arianelabs.com>
- Loading branch information
1 parent
0d7e180
commit 126a707
Showing
5 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
OPERATOR_PRIVATE_KEY= | ||
RELAY_ENDPOINT= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Web3py example | ||
Example scripts for basic operations | ||
|
||
### How to start | ||
1. **Install Solidity Compiler (`solc`)**: | ||
- Install `solc` by following the instructions in the [Solidity documentation](https://docs.soliditylang.org/en/latest/installing-solidity.html). | ||
- On Ubuntu, you can run: | ||
```sh | ||
sudo apt install solc | ||
``` | ||
|
||
2. **Set up a clean environment (with virtual env)** | ||
|
||
```bash | ||
# Install pip if it is not available: | ||
$ which pip || curl https://bootstrap.pypa.io/get-pip.py | python | ||
# Install virtualenv if it is not available: | ||
$ which virtualenv || pip install --upgrade virtualenv | ||
# *If* the above command displays an error, you can try installing as root: | ||
$ sudo pip install virtualenv | ||
# Create a virtual environment: | ||
$ virtualenv -p python3 ~/.venv-py3 | ||
# Activate your new virtual environment: | ||
$ source ~/.venv-py3/bin/activate | ||
# With virtualenv active, make sure you have the latest packaging tools | ||
$ pip install --upgrade pip setuptools | ||
# Now we can install web3.py... | ||
$ pip install --upgrade web3 | ||
# Install python-dotenv | ||
$ pip install python-dotenv | ||
# Install py-solc-x | ||
$ pip install py-solc-x | ||
``` | ||
|
||
Remember that each new terminal session requires you to reactivate your virtualenv, like: | ||
```bash | ||
$ source ~/.venv-py3/bin/activate | ||
``` | ||
|
||
3. **Create and complete `.env` file from `.env.example`** | ||
|
||
4. **Run script** | ||
```bash | ||
python scripts/test.py | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//SPDX-License-Identifier: Unlicense | ||
pragma solidity >0.5.0; | ||
|
||
contract Greeter { | ||
string public greeting; | ||
|
||
constructor() public { | ||
greeting = 'Hello'; | ||
} | ||
|
||
function setGreeting(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() view public returns (string memory) { | ||
return greeting; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# | ||
# Hedera JSON RPC Relay - Web3py Example | ||
# | ||
# Copyright (C) 2022-2024 Hedera Hashgraph, LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
import os | ||
import unittest | ||
from dotenv import load_dotenv | ||
from web3 import Web3 | ||
from solcx import install_solc, compile_source | ||
|
||
def setup_environment(): | ||
# install latest solc | ||
install_solc(version='latest') | ||
|
||
# load values from our .env file | ||
load_dotenv() | ||
OPERATOR_PRIVATE_KEY = os.getenv('OPERATOR_PRIVATE_KEY') | ||
RELAY_ENDPOINT = os.getenv('RELAY_ENDPOINT') | ||
|
||
# connect to chain | ||
w3 = Web3(Web3.HTTPProvider(RELAY_ENDPOINT)) | ||
|
||
# get account from pk | ||
acc = w3.eth.account.from_key(OPERATOR_PRIVATE_KEY) | ||
|
||
return w3, acc | ||
|
||
|
||
def get_balance(w3, acc): | ||
balance = w3.eth.get_balance(acc.address) | ||
return balance | ||
|
||
|
||
def deploy_contract(w3, acc): | ||
# read contract from file | ||
with open('contract/Greeter.sol', 'r') as f: | ||
source = f.read() | ||
|
||
# compile our Greeter contract | ||
compiled_sol = compile_source(source, output_values=['abi', 'bin']) | ||
|
||
# retrieve the contract interface | ||
contract_id, contract_interface = compiled_sol.popitem() | ||
|
||
bytecode = contract_interface['bin'] | ||
abi = contract_interface['abi'] | ||
|
||
# create web3.py contract instance | ||
Greeter = w3.eth.contract(abi=abi, bytecode=bytecode) | ||
|
||
# build transaction | ||
unsent_tx_hash = Greeter.constructor().build_transaction({ | ||
"from": acc.address, | ||
"nonce": w3.eth.get_transaction_count(acc.address), | ||
}) | ||
|
||
# sign transaction | ||
signed_tx = w3.eth.account.sign_transaction(unsent_tx_hash, private_key=acc.key) | ||
|
||
# send transaction | ||
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) | ||
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) | ||
|
||
# create instance of deployed contract | ||
greeter = w3.eth.contract( | ||
address=tx_receipt.contractAddress, | ||
abi=abi | ||
) | ||
|
||
return greeter, tx_receipt.contractAddress | ||
|
||
|
||
def contract_view_call(greeter): | ||
greeting = greeter.functions.greet().call() | ||
return greeting | ||
|
||
|
||
def contract_call(w3, acc, greeter): | ||
# build contract call transaction | ||
unsent_call_tx_hash = greeter.functions.setGreeting('Hello2').build_transaction({ | ||
"from": acc.address, | ||
"nonce": w3.eth.get_transaction_count(acc.address), | ||
}) | ||
|
||
# sign transaction | ||
signed_call_tx = w3.eth.account.sign_transaction(unsent_call_tx_hash, private_key=acc.key) | ||
|
||
# send transaction | ||
call_tx_hash = w3.eth.send_raw_transaction(signed_call_tx.rawTransaction) | ||
w3.eth.wait_for_transaction_receipt(call_tx_hash) | ||
|
||
# Verify the greeting has been updated | ||
new_greeting = greeter.functions.greet().call() | ||
return new_greeting | ||
|
||
|
||
class TestGreeterContract(unittest.TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.w3, cls.acc = setup_environment() | ||
cls.greeter, cls.contract_address = deploy_contract(cls.w3, cls.acc) | ||
|
||
def test_get_balance(self): | ||
balance = get_balance(self.w3, self.acc) | ||
self.assertIsInstance(balance, int, "Account balance is an integer") | ||
|
||
def test_deploy_contract(self): | ||
self.assertTrue(self.contract_address.startswith('0x'), "Contract address starts with '0x'") | ||
|
||
def test_call_view(self): | ||
greeting = contract_view_call(self.greeter) | ||
self.assertEqual(greeting, 'Hello', "Initial greeting matches expected value") | ||
|
||
def test_contract_call(self): | ||
new_greeting = contract_call(self.w3, self.acc, self.greeter) | ||
self.assertEqual(new_greeting, 'Hello2', "Updated greeting matches expected value") | ||
|
||
final_greeting = contract_view_call(self.greeter) | ||
self.assertEqual(final_greeting, 'Hello2', "Final greeting matches expected value after update") | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |