Skip to content

ABI와 호출 데이터 ​

컨트랙트 호출은 .app 주소로 보내는 트랜잭션이며, 그 data 필드에 호출 내용이 담깁니다. 표준 페이로드는 UTF-8 JSON입니다.

json
{"function":"transfer","args":{"to":"neuro:bob.human","amount":"250"}}

트랜잭션에서 data는 이 JSON을 문자열로 담습니다(hex로 인코딩된 페이로드도 허용됩니다). 노드는 이 바이트를 컨트랙트의 call(input_ptr, input_len) export에 전달합니다.

규칙 ​

규칙이유
메서드 이름에는 function을 사용하세요.예전 컨트랙트는 method도 받았지만, 새 코드에서는 쓰지 않아야 합니다.
신원은 호스트에서 옵니다. get_caller()를 호출하고, JSON의 caller 필드는 무시하세요.누구나 JSON에 아무 caller나 쓸 수 있습니다. 호스트 값은 트랜잭션의 검증된 서명자입니다(컨트랙트 간 호출에서는 호출한 컨트랙트).
압축된 JSON을 보내세요. :와 , 뒤에 공백을 넣지 마세요 — JSON.stringify 출력 그대로.작은 no_std 컨트랙트는 "key":를 바이트 단위로 탐색해 인자를 읽으며, 공백이 있으면 실패합니다.
금액은 10진수 문자열로, 토큰 전체 단위로: "amount":"250".노드가 변환합니다(아래 참고). 문자열을 쓰면 JavaScript에서 정밀도 손실이 없습니다.
args 전체에서 인자 이름이 겹치지 않게 하세요.바이트 탐색 컨트랙트는 페이로드 어디서든 처음 나오는 "key":를 찾으므로, args는 최상위 수준에 평탄화해 전달될 수도 있습니다.

금액은 노드가 변환합니다 ​

호출이 컨트랙트에 도달하기 전에 노드가 인자 하나를 대신 다시 씁니다.

  • 컨트랙트 호출: 10진수 문자열이나 숫자로 주어진 args.amount는 토큰 전체 단위 금액으로 간주되어, 컨트랙트의 decimals를 이용해 토큰의 최소 단위로 변환됩니다(소수 자릿수 6에서 "250" → 250000000).
  • 배포: init_args.total_supply도 init_args.decimals를 이용해 같은 방식으로 변환되며, decimals는 JSON 숫자여야 합니다(문자열은 소수 자릿수 0으로 읽힙니다).

그 밖의 모든 인자는 보낸 그대로 컨트랙트에 전달됩니다. 컨트랙트는 사람이 읽는 금액을 절대 보지 않습니다.

첨부 금액 ​

트랜잭션의 value(uNRO)는 호출이 성공한 후에 컨트랙트 자체 계정에 입금됩니다. 호출이 trap되거나 fuel이 소진되면 금액은 보낸 사람에게 남습니다. 현재는 첨부된 금액을 컨트랙트에 알려 주는 host 함수가 없습니다. 이 값이 필요한 컨트랙트는 호출 전후의 get_balance()를 비교하거나, 금액을 인자로 받아 검증할 수 있습니다.

반환 데이터와 오류 ​

컨트랙트는 set_return(ptr, len)으로 바이트를 반환합니다. 관례는 다음과 같습니다.

json
{"ok":"<value>"}            // 성공
{"error":"Unknown function"}  // 컨트랙트가 보고한 실패

trap이 발생한 컨트랙트(unreachable, fuel 소진, 범위를 벗어난 메모리 접근)는 트랜잭션을 실패시킵니다. 스토리지 변경은 롤백되고, 금액은 이동하지 않으며, 수수료와 nonce는 소비됩니다. 상태: failed.

트랜잭션 없이 반환 값을 읽으려면:

bash
curl -s -X POST "$GATEWAY/api/v1/contracts/neuro:<10 hex>.app/call" \
  -H 'Content-Type: application/json' \
  -d '{"function":"balance_of","args":{"address":"neuro:<15 hex>.human"},"dry_run":true}'

응답에는 success, return_data, gas_used와 호출이 발생시킬 이벤트가 담깁니다. 노드가 CHAIN_ENV=mainnet으로 실행 중이면 이 엔드포인트를 통한 쓰기 호출(dry_run: false)은 거부됩니다. 대신 트랜잭션을 보내세요.

생성자와 initialize ​

  • init export가 있으면 컨트랙트가 배포될 때 한 번 실행됩니다.
  • 배포에 init_args가 포함되어 있으면, 그다음 컨트랙트가 {"function":"initialize", …init_args}로 호출됩니다 — 인자는 최상위 수준에 평탄화됩니다. 컨트랙트 배포를 참고하세요.

표준 인터페이스 ​

인터페이스는 추가 WASM export가 아니라 문서화된 메서드 집합입니다. 컨트랙트는 해당 함수 이름에 응답함으로써 인터페이스를 구현합니다.

NRC-20 (대체 가능 토큰) ​

neurochain/contracts/nrc20에 구현되어 있습니다. 컨트랙트 내부에서 모든 금액은 토큰 최소 단위의 정수입니다. amount는 토큰 전체 단위로 보내면 노드가 변환합니다(위 참고).

함수인자비고
initializename, symbol, decimals, total_supply한 번만; 공급량을 호출자에게 발행하고, 호출자는 owner가 됨
name, symbol, decimals, total_supply—조회
balance_ofaddress조회
transferto, amount호출자로부터
approvespender, amount
allowanceowner, spender조회
transfer_fromfrom, to, amount호출자에게 부여된 allowance를 사용
mintto, amountowner 전용
burnamount호출자로부터
owner—조회

camelCase 별칭(balanceOf, totalSupply, transferFrom)도 허용됩니다. 송금 시 Transfer 이벤트가 발생합니다.

저장소에서 사용하는 다른 인터페이스: NRC-721 방식의 인증서(ncert)와 DAO 거버넌스(dao, gov_dao). 해당 ABI 파일은 소스 옆에 있습니다(*.abi.json).

컨트랙트 간 호출 ​

컨트랙트는 host 함수 call_contract로 다른 컨트랙트를 호출할 수 있으며, 최대 8단계 깊이(MAX_CALL_DEPTH)까지 가능합니다. 호출된 컨트랙트 안에서 get_caller()는 호출한 컨트랙트의 주소를 반환합니다. 컨트랙트 간 호출을 참고하세요.