[Solidity] 230717 study
1. Getting Set Up (~2)
touch test/CryptoZombies.js로 빈 테스트 파일 생성- Smart contract의 compile & migrate 과정은 다음과 같다
- Compile: Solidity compiler가 JSON file을 생성한다. 이는 build artifacts라고도 불리며, contract의 이진 표현법이다.
const MyAwesomeContract = artifacts.require("MyAwesomeContract")에서artifacts가 build artifacts를 의미한다.
- Migrate: Truffle이 JSON file의 update 정보를 network에 올린다
- Test: group test의 경우
contract()를 호출하며 이뤄진다.contract()는 다음 두개의 인자를 가진다string: test 대상callback: test를 작성할 위치
3. The first test - Creating a new zombie (~5)
Test는 deploy 전에, locally 수행해야 한다
Test Sequence
- Set up
- contract abstraction은 말 그대로 abstraction이기 때문에
smart conract가 상호작용하기 위해서는 JS 객체를 만들어야 한다.
const contractInstance = await MyAwesomeContract.new();와 같이 선언할 수 있다.
- test에 사용하는 인자들은
Alice's Awesome Zombie와 같은 구체적인 이름보다는Zombie #1,Zombie #2와 같은 간결한 이름을 global하게 선언하여 사용하는 것이 좋다. contractInstance.createRandomZombie(zombieName[0]);과 같이contractInstance의 함수에게 인자를 전달해 함수를 실행할 수 있다.
- Act
- 위의 Set up을 그대로 따라갔을 때, alice가 아닌 사람이 contract를 call했을 수 있다. 이런 보안 문제도 contract abstraction으로 해결할 수 있다.
const result = await contractInstance.createRandomZombie(zombieNames[0],{from:alice});- 위와 같이,
{from:alice}를 넣어서 caller를 특정할 수 있다
- 이렇게 선언한
result에는 로그 개념으로 접근할 수 있기 때문에, 다음과 같은 정보를 얻을 수 있다result.tx: tx hashresult.receipt: result의 receipt 상태가 true인지 아닌지 확인 가능
- Assert
equal(),deepEqual(): function을 실행하고, 그 결과에 따라 errorthrow를 하기도 함
6. Keeping the Fun in the Game (~7)
assert()사용
8. Zombie Transfers
Transfer Scenarios
- ERC721에 따라 다음 2개의 transfer scenario가 예상된다.
- Alice가 자신의 zombie를 직접 transfer 하는 경우:
transferFrom을 직접 실행 - Alice가 자신의 zombie에 대한 Bob의 접근을 허용하고, Alice 혹은 Bob이 transfer 하는 경우:
approve를 실행한 뒤transferFrom을 실행
- Alice가 자신의 zombie를 직접 transfer 하는 경우:
Context Function
-
context("with the single-step transfer scenario", async () => { it("should transfer a zombie", async () => { // TODO: Test the single-step transfer scenario. }) }) context("with the two-step transfer scenario", async () => { it("should approve and then transfer a zombie when the approved address calls transferFrom", async () => { // TODO: Test the two-step scenario. The approved address calls transferFrom }) it("should approve and then transfer a zombie when the owner calls transferFrom", async () => { // TODO: Test the two-step scenario. The owner calls transferFrom }) }) - 위와 같이, multiple scenario에 대해
context함수를 이용해 test 결과를 분리할 수 있다 - 만약 multiple scenario에서 한
context내의 test 결과가 정상적으로 작동할 때 필연적으로 상충하는 경우, 순차적인 테스트를 위해 함수 앞에 문자x를 붙일 수 있다.x가 붙어있는 context에 대해, truffle과 같은 compiler는 테스트를 진행하지 않는다