2-intro-of-iost/Smart-contract
스마트 컨트랙트는 블록에 담긴 트랜잭션을 받아서 실행하여, 스마트 컨트랙트 내부의 변수 값을 유지합니다. 이는 IOST 블록체인 위에서 일어나기 때문에 일단 트랜잭션이 블록에 들어가게 되면 "되돌릴 수 없는" 비가역적 성질을 지니게 됩니다. IOST는 ABI 인터페이스와 플러그 앤 플레이, 여러 개발 언어를 지원하여 블록체인을 좀 더 쉽게 사용할 수 있게합니다.
ABI 인터페이스
IOST 스마트 컨트랙트는 ABI를 통해서 IOST 블록체인 네트워크와 상호작용 할 수 있습니다. ABI는 쉽게 말해, JSON으로 정의된 정보인데, 이 정보에는 컨트랙트의 이름, 파라미터들의 타입 등 컨트랙트 함수 실행에 필요한 정보가 담기게 됩니다. 현재 지원되는 타입으로는 string, number, bool이 있습니다.
스마트 컨트랙트 함수를 실행할 때에는 ABI에 정의된 대로 파라미터 타입을 맞춰주어야 하며, 이를 맞춰주지 않은 채로 컨트랙트 함수 실행을 하게되면 트랜잭션 수수료가 발생하고 실제로 함수가 정상적으로 실행되지 않습니다.
// example luckybet.js.abi
{
"lang": "javascript",
"version": "1.0.0",
"abi": [
{
"name": "bet",
"args": [
"string",
"number",
"number",
"number"
]
}
]
}
모든 트랜잭션에는 Action이라고 하는 트랜잭션을 일으키는 구현체가 존재하는데, 각 Action은 ABI에 대한 호출이라고 생각하면 된다. 모든 트랜잭션은 블록체인 내에서 strict serial을 만들어 이중 지불 공격을 막는다.
type Action struct {
Contract string
ActionName string
Data string // A JSON Array of args
}
스마트 컨트랙트 내에서 BlockChain.call()을 통해 ABI interface를 호출하여, 리턴되는 값을 얻을 수 있습니다. 이러한 시스템은 콜 스택에 로그를 남겨 이중 지불(double-spend)를 방지합니다.
다중 언어 지원
IOST에선, 여러 언어로 스마트 컨트랙트를 개발 할 수 있습니다. 현재는 V8 엔진 위에서 자바스크립트로 스마트 컨트랙트를 개발할 수 있고, 고 성능의 트랜잭션을 처리 할 수 있는 golang VM 모듈도 존재합니다.
IOST의 스마트 컨트랙트 엔진은 monitor, VM, host라는 세 가지 요소로 구성됩니다. monitor는 ABI 콜을 적절한 VM으로 보내주는 글로벌 제어 장치이고, VM은 스마트 컨트랙트의 버츄얼 머신 구현체입니다. 마지막으로 host는 런타임 환경을 구성하고 컨트랙트가 올바른 컨텍스트 내에서 실행 될 수 있게 합니다.
스마트 컨트랙트 '권한' 시스템
IOST의 트랜잭션은 다중 서명(multiple signatures)를 지원합니다. 스마트 컨트랙트 내에 RequireAuth()라는 함수가 존재하는데, 이를 통해서 현재 트랜잭션의 컨텍스트가 특정한 ID의 서명을 가지고 있는지 확인 할 수 있습니다. 또한 스마트 컨트랙트 간의 호출은 이러한 서명 인증 전달하는데, 예를 들면 A 컨트랙트의 a라는 함수가 B 컨트랙트의 b를 호출하는 구조인 경우, 사용자가 A 컨트랙트의 a 함수를 호출할 때 서명에 대해서 인증이 되었다면, 인증되었다는 정보가 B 컨트랙트의 b 함수에서도 그대로 전달됩니다.
스마트 컨트랙트는 콜 스택을 체크하여 현재 누가 이 ABI를 호출하였는지에 대해서 알려줄 수 있습니다. 이를 통해 ABI 호출한 사람이 누구인지에 따라서 다른 로직을 적용하게끔 개발할 수 있습니다.
스마트 컨트랙트는 컨트랙트를 업그레이드 하거나 삭제할 수 있는 특별한 권한이 존재하는데, 이들은 각각 can_update()와 can_destroy() 함수를 통해 권한 여부에 대해서 알 수 있습니다.
컨트랙트 실행(Call) 결과
컨트랙트 함수 실행 후, 스마트 컨트랙트는 TxReceipt를 만들어 블록에 집어넣고 컨센서스(합의)를 기다립니다. TxReceipt가 합의를 거쳐 최종적으로 블록에 들어가게 되면 RPC를 이용해서 블록체인에서 발생한 TxReceipt 들을 조회할 수 있습니다.
$ curl -X GET \
http://52.192.65.220:30001/getTxReceiptByTxHash/G62UQbq9u8MP8cNLD9HUpMFtstTvRUAJ4avzKiAJc86f \
-H 'Cache-Control: no-cache' \
-H 'Postman-Token: 2442fe9c-0c80-4459-a9e6-0001bbde3dbb'l
{
"txReceiptRaw": {
"txHash": "4CjfeOvtjmhdZep9WG5pPoEoLPu90avQkbGKefTKNaw=",
"gasUsage": "1129",
"status": {},
"succActionNum": 1
},
"hash": "eU9xHGM15gfDInAG7Y8q3RB9mMm1Pekmj4RUUHWFkqU="
}
