본문 바로가기
블록체인/[파공이]파이썬으로 공부하는 이더리움(Web3)

[web3] 이더리움 블록체인으로 나만의 계산기 만들기!!(feat. Python)

by 일등박사 2023. 3. 28.
728x90

여러분은 세상을 믿으시나요??

구글에서는 계산기를 제공하고있습니다.

이 계산기를 믿을 수 있을까요!?

 

여러분이 수식을 입력하면!!! 

이 수식은 구글의 서버로 가서 계산이 된 뒤 여러분에게 보여지게 됩니다.

그런데!! 만약 구글이 이 계산 프로세스에 장난을 쳤으면??

여러분은 그 것을 알아차릴 수 있을까요?

그 게산이 정말 중요한 계산이었다면!!!

어떻하지요!?


블록체인은 탈중앙화를 강조합니다!!

구글에 의존하는 것이 아니라, 모두가 볼 수 있는 코드(계산기)를

공개된 블록체인 네트워크에 배포하고, 해당 시스템을 통해 활용(계산) 한다면

믿고 맡길 수 있겠지요!?

 

이제부터!! 이더리움 테스트넷에 계산기를 만들어보겠습니다!!!!

 

1. Web3접속 후 계산기 스마트 컨트랙트 컴파일 하기

from web3 import Web3
import requests
import json
from decimal import Decimal
from solcx import compile_standard, install_solc


ETHTEST_ADR = "https://rpc2.sepolia.org/"
chain_id = 11155111


## 내 지갑 정보를 미리 세팅해둡시다!!
my_wallet = '0xEfBDBfF11A678d9F9EE881E91fDb1F713bc066BC'
my_password = "{내 지갑의 비밀번호!!}"

### web3 패키지로 이더리움 테스트넷에 접속!
w3 = Web3(Web3.HTTPProvider(ETHTEST_ADR))

# solc 버젼이 맞게 설치
install_solc('0.8.0')

contract_func  = '''
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Calculator {
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    function subtract(uint256 a, uint256 b) public pure returns (uint256) {
        require(b <= a, "Subtraction result cannot be negative");
        return a - b;
    }

    function multiply(uint256 a, uint256 b) public pure returns (uint256) {
        return a * b;
    }

    function divide(uint256 a, uint256 b) public pure returns (uint256) {
        require(b > 0, "Cannot divide by zero");
        return a / b;
    }
}

'''

## solidity 언어를 컴퍼일하기!!!
compiled_sol = compile_standard(
    {
        "language": "Solidity",
        "sources": {"my_calculator.sol": {"content": contract_func}},
        "settings": {
            "outputSelection": {
                "*": {
                    "*": ["abi", "metadata", "evm.bytecode", "evm.bytecode.sourceMap"] # output needed to interact with and deploy contract 
                }
            }
        },
    },
    solc_version="0.8.0",
)

# 프린트를 보면 내용을 알 수 있다
print(compiled_sol)

## Bytecode와 abi 뽑디

# get bytecode
bytecode = compiled_sol["contracts"]["my_calculator.sol"]["Calculator"]["evm"]["bytecode"]["object"]
# get abia
abi = json.loads(compiled_sol["contracts"]["my_calculator.sol"]["Calculator"]["metadata"])["output"]["abi"]
abi

 

위와 같이 간단하게 계산기 스마트컨트랙트를 컴파일 할 수 있었습니다!!!

 Solidity, 솔리디티가 어렵다구요!? 그렇지 않아요!!!!

chatgpt 가 다 해주니까요!!

## 더하기
contact_list = w3.eth.contract(address=transaction_receipt.contractAddress, abi=abi)
print(contact_list.functions.add(3,5).call())
## 빼기
contact_list = w3.eth.contract(address=transaction_receipt.contractAddress, abi=abi)
print(contact_list.functions.subtract(5,3).call())
## 곱하기
contact_list = w3.eth.contract(address=transaction_receipt.contractAddress, abi=abi)
print(contact_list.functions.multiply(5,3).call())
## 나누기
contact_list = w3.eth.contract(address=transaction_receipt.contractAddress, abi=abi)
print(contact_list.functions.divide(5,3).call())

 

2. 스마트컨트랙트 배포하기!!

 > 이제 나의 스마트컨트랙트를 이더리움 망에 배포합니다!!

# For connecting to ganache
w3 = Web3(Web3.HTTPProvider(ETHTEST_ADR))


ContactList = w3.eth.contract(abi=abi, bytecode=bytecode)# Get the number of latest transaction
nonce = w3.eth.get_transaction_count(my_wallet)


# build transaction
transaction = ContactList.constructor().build_transaction(
    {
        "chainId": chain_id,
        "gasPrice": w3.eth.gas_price,
        "from": my_wallet,
        "nonce": nonce,
    }
)
# Sign the transaction
sign_transaction = w3.eth.account.sign_transaction(transaction, private_key=my_password)
print("Deploying Contract!")
# Send the transaction
transaction_hash = w3.eth.send_raw_transaction(sign_transaction.rawTransaction)
# Wait for the transaction to be mined, and get the transaction receipt
print("Waiting for transaction to finish...")
transaction_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash)
print(f"Done! Contract deployed to {transaction_receipt.contractAddress}")

내 스마트컨트랙트가 아래 주소에 잘 저장되었다구합니다!!

0xd66f259C9cfA26702F942D73c5DD4E77De2259ff

3. 스마트컨트랙트 확인하기!!

 > 정말일까요!?? 더하기, 뺴기 곱하기 등 함수를 실행해봅니다!!!

 

정말 정확하네요!!!

 

4. 여러사람에게 배포하기!!

 > 이제 분산원장에 저장된 위 내용을 여러분들께 공유합니다!!

 > 언제 어디서나 안전한 계산기를 사용할 수 있습니다!!

 > 아래 코드를 실행해보세요!!

from web3 import Web3
import requests
import json
from decimal import Decimal
from solcx import compile_standard, install_solc

my_abi = [{'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'add',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'divide',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'multiply',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'subtract',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'}]

ETHTEST_ADR = "https://rpc2.sepolia.org/"
chain_id = 11155111

### 기존 계정조회하기 USING Web3
w3 = Web3(Web3.HTTPProvider(ETHTEST_ADR))

my_abi = [{'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'add',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'divide',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'multiply',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'},
 {'inputs': [{'internalType': 'uint256', 'name': 'a', 'type': 'uint256'},
   {'internalType': 'uint256', 'name': 'b', 'type': 'uint256'}],
  'name': 'subtract',
  'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
  'stateMutability': 'pure',
  'type': 'function'}]

contact_list = w3.eth.contract(address="0xd66f259C9cfA26702F942D73c5DD4E77De2259ff", abi=my_abi)
print(contact_list.functions.add(3,5).call())

이제!! 믿음직한 계산기가 생겼어요!^^

 

5. 확인하기!!!

블록스캔에서 확인해보아요!!

 

https://sepolia.etherscan.io/address/0xd66f259C9cfA26702F942D73c5DD4E77De2259ff

 

Contract Address 0xd66f259C9cfA26702F942D73c5DD4E77De2259ff | Etherscan

The Contract Address 0xd66f259C9cfA26702F942D73c5DD4E77De2259ff page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on Etherscan.

sepolia.etherscan.io

잘 생성되었지요!?^^

 

728x90

댓글