이더리움을 통해 DApp을 구현할때 대부분 web3 라이브러리를 사용하는데 js에 대한 자료들은 엄청 많이 존재하고 있지만 py에 대한 자료들이 적어서 삽질한 내용에 대해 남겨보려고 한다.
Private Blockchain에 정보를 저장하고 가져와서 써서 Gas나 데이터량 같은 것은 신경을 안썻다는 것을 참고 했으면 좋겠다. 또한 해커톤때 구현한 코드라 급하게 더럽게 짯었다.
먼저 기본적인 모듈들은 이렇게 사용하였다.
from web3 import Web3, HTTPProvider
from solc import compile_source
from web3.contract import ConciseContract
그런 이후 Solidity 코드를 정의해주는데 다음과 같은 형식으로 정의하게 된다.
contract_source_code = '''
pragma solidity ^0.4.0;
// solidity code
'''
저 변수 안에 솔리디티 코드를 사용하면 되는데 나는 변수를 Set하고 Get 하는 함수 두개를 작성하엿다.
contract contract_Register {
string public data;
function setLog(string _data) public {
data = _data;
}
function getLog() constant returns (string) {
return (data);
}
}
스마트 컨트렉트 내에도 많은 변수 타입들이 존재하지만 여기엔 포스팅 하지 않겠다.
먼저 contract 의 이름은 contract_Register이다. 이는 나중에 Solidity를 컴파일 할때 사용하게 된다.
함수의 형태는
funtion function_name($arg) returns(리턴을 할것인가 안할것인가) ($return value type) {}
그래서 결과적으로 이러한 Solidity Code를 컴파일 하는 Python code는 다음과 같다.
compiled_sol = compile_source(contract_source_code)
contract_interface = compiled_sol['<stdin>:contract_Register']
이제는 geth에 연결시킬 차례이다.
provider = HTTPProvider('http://0.0.0.0:9945')
w3 = Web3(provider)
그 후엔 컨트렉트를 생성하고 deploy를 하여 transaction hash 값을 받아온다.
그 다음 부분이 가장 삽질을 오래 했던 부분이다. deploy를 한다고 해도 마이닝이 되어야 블록에 올라가기에 Receipt 이 바로 안떨어지게 되는데 web.js는 애초에 비동기이기 때문에 상관이 없다 하지만 web3.py는 이러한 부분을 직접 처리해주어야 한다.
while w3.eth.getTransactionReceipt(tx_hash) is None:
time.sleep(0.1)
아래의 깃허브 링크는 교보생명 해커톤 당시 0박2일로 실속을 위해서 만들어진 코드이다. 그렇기에 그저 참조만 하길 바란다.