How to SCORE #LAST
IconScoreBase, Utility Functions, Common Classes
이번 시리즈를 이해하기 위해서는 Python
언어 및 ICON 이 제공하는 CLI 개발도구인 T-Bears 및 ICON SDK 활용법에 대한 약간의 사전지식이 필요합니다.
다섯번째 파트에서는 InterfaceScore
에 대해 살펴보았습니다. 혹시 아직 못보신 분이 있으시면 파트 5을 먼저 보시는 것을 권장합니다.
시리즈의 마지막 파트에서는 SCORE의 가장 기본이 되는 IconScoreBase
의 Built-in Properties & Functions와 함께 Common Classes(Address)
, API Functions(revert, sha3_256, json_dumps, json_loads)
에 대해 살펴보겠습니다.
Table of Contents
IconScoreBase
Abstract Methods
- __init__
- on_install
- on_update
Built-in Properties
- msg
- tx
- icx
- db
- …
Built-in Functions
- create_interface_score
Common Classes
- Address
API Functions
- revert
- sha3_256
- json_dumps
- json_loads
IconScoreBase
IconScoreBase
는 SCORE의 가장 기본이 되는 클래스로 SCORE 실행을 위한 환경 및 기능을 제공합니다. 모든 SCORE 클래스는 IconScoreBase
클래스를 상속받아 작성되어야 합니다.
Abstract Methods
__init__
실행 시기 : 클래스의 생성자로 SCORE 클래스의 인스턴스가 생성될 때 마다 실행됩니다.
Usage : SCORE 내부에서 사용할 변수를 선언하기에 적합합니다. 따라서 데이터 저장 및 변경과 같은 쓰기 작업은 권장하지 않습니다. SCORE 에서 사용할 멤버 변수들은 모두 state DB에 의해 관리되어야 합니다.
def __init__(self, db: IconScoreDatabase) -> None:
super().__init__(db)
부모클래스의
__init__
메소드를 반드시 호출해야 합니다.
on_install
실행 시기 : SCORE가 배포되는 순간 단 한번 실행됩니다.
Usage : __init__
에서 선언한 변수들의 초기값을 설정하기에 적합합니다.
def on_install(self) -> None:
super().on_install()
부모클래스의
on_install
메소드를 반드시 호출해야 합니다.
on_update
실행 시기 : 기존에 배포된 SCORE 가 업데이트될 때 마다 실행됩니다.
Usage : 기존의 상태(state)들을 새로운 형태로 저장하기에 적합합니다.
def on_update(self) -> None:
super().on_update()
부모클래스의
on_update
메소드를 반드시 호출해야 합니다.
Built-in Properties
msg
msg
는 SCORE의 메소드를 호출하거나 ICX
를 전송하는 요청들에 대한 전송받은 ICX(self.msg.value)
, 송신 주체의 Address(self.msg.sender)
와 같은 정보를 가지고 있습니다.
- self.msg.sender
msg.sender
는 SCORE의 external
메소드를 호출하거나 ICX
를 전송한 주체의 Address
를 의미합니다.
만약 사용자(EOA)가 아닌 SCORE가 InterfaceScore
를 통해 external
메소드를 호출하거나 self.icx.send
& self.icx.transfer
를 통해 ICX
를 전송하는 경우 msg.sender
는 메소드를 호출하거나 ICX
를 전송한 SCORE의 Address
가 됩니다.
- self.msg.value
msg.value
는 트랜잭션이 단순한 ICX
전송인지, 아니면 external
메소드를 호출하며 함께 ICX
를 전송한 것인지와 상관 없이 SCORE로 전송된 ICX
의 양을 의미합니다.
tx
tx
는 트랜잭션에 대한 origin
, index
, hash
, timestamp
, nonce
와 같은 여러가지 정보를 가지고 있습니다.
- self.tx.origin
트랜잭션을 생성한 사용자(EOA)를 의미합니다. self.msg.sender
와 같이 Address
를 의미하지만 self.tx.origin
은 self.msg.sender
와 달리 icx_call
이 아닌 icx_sendTransaction
을 통한 트랜잭션에서만 활용될 수 있습니다.
icx_call
의 경우 self.msg.sender
는 from
으로 입력된 주소가 할당되어 있는데 반해 self.tx
는 None
으로 self.tx.origin
은 NoneType
의 origin
속성이 됨으로 활용할 수 없습니다.
Interface
를 통해 SCORE가 메소드를 호출하는 경우self.tx.origin
은 해당 트랜잭션을 생성한 사용자(EOA)를 의미하지만,self.msg.sender
는 다른 SCORE의 메소드를 호출한 SCORE 주소를 의미합니다.
@external(readOnly=True)
def queryCall(self):
return f'{self.msg.sender}, {self.tx}' # from 주소, None 반환
- self.tx.index
트랜잭션이 포함된 블록에서 해당 트랜잭션의 인덱스를 의미합니다.
- self.tx.hash
트랜잭션의 해시를 의미합니다. 이전에 실행된 트랜잭션과 동일한 해시를 지닌 트랜잭션은 다시 실행될 수 없습니다.
- self.tx.timestamp
트랜잭션이 생성된 시간을 의미합니다.
- self.tx.nonce
동일한 해시를 가진 트랜잭션 생성을 방지하기 위해 임의로 입력한 값을 의미합니다. 이전에 실행된 트랜잭션과 동일한 해시를 지닌 트랜잭션은 실행될 수 없습니다.
icx
icx
는 SCORE가 ICX
를 전송할 때 사용됩니다.
- self.icx.transfer
self.icx.transfer(receiver: Address, amount: int)
tranfer
메소드를 통해 amount
만큼의 ICX
를 receiver
주소로 전송합니다.
ICX
전송이 성공적으로 실행되는 경우 True
를 반환하지만, SCORE의 balance
가 충분하지 않아 ICX
전송이 실패하는 경우, Out of balance
라는 메시지와 함께 InvalidParamsException
을 발생시킵니다. 발생한 Exception에 대한 별도의 처리가 없다면 트랜잭션은 실패하며, 이전까지의 상태 변화를 되돌립니다.
try/except
를 통해 발생하는InvalidParamsException
을 처리할 수 있습니다.
- self.icx.send
self.icx.send(receiver: Address, amount: int)
send
메소드를 통해 amount
만큼의 ICX
를 receiver
주소로 전송합니다.
ICX
전송이 성공적으로 실행되는 경우 transfer
와 마찬가지로 True
를 반환합니다. 하지만 SCORE의 balance
가 충분하지 않아 ICX
전송이 실패하는 경우 send
는 InvalidParamsException
을 발생시키지 않고 False
를 반환합니다. send
에 의한 ICX
전송이 실패하더라도 트랜잭션은 실패하지 않습니다.
if/else
를 통해ICX
전송이 실패한 경우에 대한 처리가 가능합니다.
db
db
는 SCORE에서 state DB에 저장된 데이터에 접근하기 위해 사용됩니다.
@property
def _array_db(self):
return ArrayDB('array_db', self.db, str) def __init__(self, db: IconScoreDatabase):
super.__init__(db)
var_db = VarDB('var_db', db, str)
__init__
에 파라미터로 전달되어VarDB
에 입력되는db
는ArrayDB
에 전달되는self.db
와 동일합니다.self.db == db -> True
address, owner, block_height, now
- address
self.address
해당 SCORE의 Address
를 의미합니다.
- owner
self.owner
SCORE를 배포한 사용자(EOA)의 Address
를 의미합니다.
- block_height
self.block_height
실행된 트랜잭션이 포함된 블록의 높이를 의미합니다.
- now
self.now()
실행된 트랜잭션이 포함된 블록이 생성된 시간을 반환합니다.
Built-in Functions
create_interface_score
create_interface_score
메소드는 InterfaceScore
를 상속받은 클래스와 사용할 SCORE의 Address
를 파라미터로 입력받아 해당 SCORE의 external
메소드에 접근할 수 있는 Interface
객체를 반환합니다.
self.create_interface_score(ScoreAddress, InterfaceClass)
Common Classes
Address
- body
-> bytes
20 bytes 크기의 Address body
를 반환합니다. Address
의 body
는 hx
, cx
와 같은 prefix
부분을 제외한 주소를 의미합니다.
- from_bytes(buf: bytes)
-> Address
입력받는 bytes 데이터(Address.to_bytes)
를 바탕으로 Address
를 생성하여 반환합니다.
- from_data(prefix: int, data: bytes)
-> Address
입력받는 bytes 데이터(Public Key)
와 prefix
를 바탕으로 Address
를 생성하여 반환합니다.
- from_string(address: str)
-> Address
입력받는 42 글자의 Address
형식을 갖춘 문자열 데이터를 바탕으로 Address
를 생성하여 반환합니다.
- is_contract
-> bool
해당 Address
가 SCORE인지 확인하여, bool
타입을 반환합니다. Address
가 SCORE
인 경우 True
, EOA
인 경우 False
를 반환합니다.
- prefix
-> int
해당 Address
의 prefix
를 반환합니다. SCORE의 경우 1
, EOA의 경우 0
를 반환합니다. prefix
를 str
타입으로 변환하는 경우 EOA는 ‘0’
이 아닌 ‘hx’
로 SCORE는 ‘1’
이 아닌 ‘cx’
로 변환됩니다.
- to_bytes()
-> bytes
Address
를 bytes
데이터로 전환하여 반환합니다.
API Functions
revert(message: str) -> None
IconScoreBase
에서utility function
으로 제공되는 기능으로,revert
함수가 호출되는 경우RevertException
을 발생시키고, 트랜잭션에 의해 변화된 상태를 이전 상태로 복구시킵니다.
revert(message: str)
의도하지 않은 상황이 발생하는 경우,
revert
함수를 호출하는 것으로 해당 트랜잭션에 의한 상태 변화를 강제로 되돌릴 수 있습니다.
sha3_256(data: bytes) -> bytes
- 입력받은 data를 바탕을 해시를 계산하여 반환합니다.
sha3_256(data: bytes)
json_dumps(obj: Any, **kwargs) -> str
Python Object
를 JSON string
으로 전환하여 반환합니다. JSON string
으로 전환 가능한 Python Object
들은 이어지는 Python — JSON Conversion Table
을 통해 확인해 봅시다.
json_dumps(obj: Any, **kwargs)
json_loads(src: str, **kwargs) -> Any
JSON string
을 Python object
로 전환하여 반환합니다.
json_loads(src: str, **kwargs)
ICON 과 관련된 추가적인 질문사항이 있는 경우, ICON 의 공식 개발자포럼 혹은 페이스북 그룹에 질문하시면 답변을 얻으실 수 있습니다.