TVM 업그레이드 2023.07
이 업그레이드는 2023년 12월부터 메인넷에서 실행을 시작했습니다.
c7
c7은 컨트랙트 실행에 필요한 로컬 컨텍스트 정보(예: 시간, 시간 간격, 네트워크 구성 등 )가 저장되는 레지스터입니다.
C7 튜플이 10개 요소에서 14개 요소로 확장되었습니다:
- 10: 스마트 컨트랙트 자체의 코드가 있는 '셀'입니다.
- 11: '[정수, maybe_dict]`: 수신 메시지의 TON 값, 외화입니다.
- 12: '정수', 저장 단계에서 징수되는 수수료.
- 13: 이전 블록에 대한 정보가 포함된 '튜플'.
10 현재 스마트 컨트랙트의 코드는 TVM 레벨에서 실행 가능한 연속체 로만 표시되며 셀로 변환할 수 없습니다. 이 코드는 종종 같은 종류의 이웃 컨트랙트 를 승인하는 데 사용됩니다(예: jetton-wallet이 jetton-wallet을 승인하는 경우). 현재로서는 코드 셀을 스토리지에 명시적으로 저장하기 위해 스토리지와 init_wrapper를 더 번거롭게 만드는 것이 필요합니다. 코드에 10을 사용하면 tvm의 에버스케일 업데이트와 호환됩니다.
11 현재 수신 메시지의 값은 TVM 시작 후 스택에 표시되므로 실행 중에 필요한 경우
전역 변수에 저장하거나 로컬 변수
(funC 수준에서는 모든 함수에 추가 msg_value
인수처럼 보입니다)를 통해 전달해야 합니다.
이를 11 요소에 넣으면 컨트랙트 잔액의 동작이 반복됩니다: 스택과 C7에 모두 표시됩니다.
**현재 저장 수수료를 계산하는 유일한 방법은 이전 거래의 잔액을 저장하는 것입니다. 어떻게든 이전 거래에서 가스 사용량을 계산한 다음 현재 잔액에서 메시지 값을 뺀 값과 비교하는 것입니다. 한편, 종종 저장 수수료를 고려하는 것이 바람직합니다.
13 현재 이전 블록에 대한 데이터를 검색할 수 있는 방법이 없습니다. TON의 킬 기능 중 하나는 모든 구조 가 머클 프루프 친화적인 셀의 백(트리)이며, TVM 역시 셀과 머클 프루프 친화적이라는 것입니다. 이렇게 블록에 대한 정보를 TVM 컨텍스트에 포함하면 많은 신뢰 없는 시나리오를 만들 수 있습니다: 컨트랙트 A가 컨트랙트 B의 트랜잭션을 확인할 수 있고(B의 협력 없이), 끊어진 메시지 체인을 복구할 수 있으며(복구 컨트랙트가 일부 거래가 발생했지만 되돌려진 증거를 가져와 확인할 때), 마스터체인 블록 해시도 알고 있어야 일부 검증 피셔맨 기능을 온체인으로 만들 수 있습니다.
블록 ID는 다음 형식으로 표시됩니다:
[ wc:Integer shard:Integer seqno:Integer root_hash:Integer file_hash:Integer ] = BlockId;
[ last_mc_blocks:[BlockId0, BlockId1, ..., BlockId15]
prev_key_block:BlockId ] : PrevBlocksInfo
마스터체인의 마지막 16개 블록의 ID와 마지막 키 블록이 포함됩니다(마스터체인 seqno가 16개 미만인 경우 그 이하). 샤드블록에 데이터를 포함하면 병합/분할 이벤트로 인해 일부 데이터 가용성 문제가 발생할 수 있으며, 반드시 필요한 것은 아니므로(모든 이벤트/데이터는 마스터체인 블록을 사용하여 증명할 수 있으므로) 포함하지 않기로 결정했습니다.
새로운 옵코드
새 옵코드에서 가스 비용을 선택할 때의 경험 법칙은 보통(옵코드 길이로 계산)보다 작아서는 안 되며 가스 단위당 20ns를 넘지 않아야 한다는 것입니다.
새로운 c7 값으로 작동하는 옵코드
각 26개 가스, PREVMCBLOCKS
및 PREVKEYBLOCK
(34개 가스)을 제외합니다.
xxxxxxxxxxxxxxxxxx 다섯 번째 구문 | xxxxxxxxx 스택 | xxxxxxxxxxxxxxxxxxxxxxxxxxx 설명 |
---|---|---|
MYCODE | - c | c7에서 스마트 컨트랙트 코드를 검색합니다. |
'들어오는 값' | - t | c7에서 수신 메시지 값을 검색합니다. |
스토리지 | - i | c7에서 스토리지 단계 수수료의 가치를 검색합니다. |
'이전블록인포튜플' | - t | c7에서 PrevBlocksInfo: [last_mc_블록, prev_key_블록] 을 가져옵니다. |
PREVMC블록 | - t | 마지막mc블록`만 검색합니다. |
'이전 키 블록' | - t | 이전키블록`만 검색합니다. |
GLOBALID | - i | 19개 네트워크 구성에서 global_id 를 검색합니다. |
가스
xxxxxxxxxxxx 파이브 구문 | xxxxxxxx 스택 | xxxxxxxxxxxxxxxxxx 설명 |
---|---|---|
가스 소비 | - g_c | 지금까지 VM이 소비한 가스(이 명령 포함)를 반환합니다. 26 gas |
산술
나누기 연산자](https://docs.ton.org/learn/tvm-instructions/instructions#52-division)(\`A9mscdf\`)의 새로운 변형이 추가되었습니다:
d=0
은 스택에서 정수를 하나 더 가져와 나누기/rshift 전 중간값에 더합니다. 이 연산은 몫과 나머지를 모두 반환합니다(d=3
과 마찬가지로).
조용한 변형도 사용할 수 있습니다(예: QMULADDDIVMOD
또는 QUIET MULADDDIVMOD
).
반환 값이 257비트 정수에 맞지 않거나 제곱이 0인 경우, 조용하지 않은 연산은 정수 오버플로 예외를 던집니다. 조용한 연산은 맞지 않는 값 대신 'NaN'을 반환합니다(제곱이 0인 경우 두 개의 'NaN'이 반환됨).
가스 비용은 10에 옵코드 길이를 더한 값입니다: 대부분의 옵코드는 26, LSHIFT#
/RSHIFT#
는 +8, 조용한 경우 +8입니다.
xxxxxxxxxxxxxxxxxx 다섯 번째 구문 | 스택 스택 |
---|---|
멀라디브모드 | x y w z - q=floor((xy+w)/z) r=(xy+w)-zq |
muladddivmodr | x y w z - q=라운드((xy+w)/z) r=(xy+w)-zq |
muladddivmodc | x y w z - q=ceil((xy+w)/z) r=(xy+w)-zq |
ADDDIVMOD | x w z - q=floor((x+w)/z) r=(x+w)-zq |
ADDDIVMODR | x w z - q=라운드((x+w)/z) r=(x+w)-zq |
ADDDIVMODC | X W Y - Q=CEIL((X+W)/Z) R=(X+W)-ZQ |
ADDRSHIFTMOD | `x w z - q=floor((x+w)/2^z) r=(x+w)-q2^z`* |
addrshiftmodr | `x w z - q=라운드((x+w)/2^z) r=(x+w)-q2^z`* |
addrshiftmodc | `X W Z - Q=CEIL((X+W)/2^Z) R=(X+W)-Q2^Z`* |
z ADDRSHIFT#MOD | `x w - q=floor((x+w)/2^z) r=(x+w)-q2^z`* |
z ADDRSHIFTR#MOD | `x w - q=라운드((x+w)/2^z) r=(x+w)-q2^z`* |
z ADDRSHIFTC#MOD | `X W - Q=CEIL((X+W)/2^Z) R=(X+W)-Q2^Z`* |
muladdrshiftmod | `x y w z - q=floor((xy+w)/2^z) r=(xy+w)-q2^z`* |
muladdrshiftrmod | `x y w z - q=라운드((xy+w)/2^z) r=(xy+w)-q2^z`* |
muladdrshiftcmod | `x y w z - q=ceil((xy+w)/2^z) r=(xy+w)-q2^z`* |
z MULADDRSHIFT#MOD | `x y w - q=floor((xy+w)/2^z) r=(xy+w)-q2^z`* |
z MULADDRSHIFTR#MOD | `x y w - q=라운드((xy+w)/2^z) r=(xy+w)-q2^z`* |
z MULADDRSHIFTC#MOD | `X Y W - Q=CEIL((XY+W)/2^Z) R=(XY+W)-Q2^Z`* |
lshiftadddivmod | `x w z y - q=floor((x2^y+w)/z) r=(x2^y+w)-zq` |
lshiftadddivmodr | `x w z y - q=라운드((x2^y+w)/z) r=(x2^y+w)-zq` |
lshiftadddivmodc | `x w z y - q=ceil((x2^y+w)/z) r=(x2^y+w)-zq` |
y LSHIFT#ADDDIVMOD | `x w z - q=floor((x2^y+w)/z) r=(x2^y+w)-zq` |
y LSHIFT#ADDDIVMODR | `x w z - q=라운드((x2^y+w)/z) r=(x2^y+w)-zq` |
y LSHIFT#ADDDIVMODC | `X W Z - Q=CEIL((X2^Y+W)/Z) R=(X2^Y+W)-ZQ` |
스택 작업
현재 모든 스택 연산의 인수는 256으로 제한됩니다.
즉, 스택이 256보다 깊어지면 깊은 스택 요소를 관리하기가 어려워집니다.
대부분의 경우 이러한 제한에 대한 안전상의 이유는 없습니다. 즉, 너무 비싼 연산을 방지하기 위해 인수를 제한하지 않습니다.
계산 시간이 인자 값에 선형적으로 의존하는 ROLLREV
와 같은 일부 대용량 스택 연산의 경우 가스 비용도 인자 값에 선형적으로 의존합니다.
- 이제
PICK
,ROLL
,ROLLREV
,BLKSWX
,REVX
,DROPX
,XCHGX
,CHKDEPTH
,ONLYTOPX
,ONLYX
의 인수가 무제한으로 허용됩니다. - 롤
,
롤레브,
레브엑스,
온리탑엑스는 인수가 클 때 더 많은 가스를 소비합니다: 추가 가스 비용은
최대(인수-255,0)` (256보다 작은 인수의 경우 가스 소비는 일정하며 현재 동작과 일치합니다). - BLKSWX
의 경우 추가 비용은
max(arg1+arg2-255,0)입니다(현재
arg1과
arg2`가 모두 255로 제한되므로 현재 동작과 일치하지 않습니다).
해시
현재 TVM에서는 셀/슬라이스에 대한 표현 해시 계산과 데이터의 sha256, 두 가지 해시 연산만 가능하지만 최대 127바이트(하나의 셀에 그 정도의 데이터만 들어갈 수 있음)까지만 가능합니다.
HASHEXT[A][R]_(HASH)` 연산 계열이 추가됩니다:
xxxxxxxxxxxxxxxxx 다섯 번째 구문 | xxxxxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxxxx 설명 |
---|---|---|
해시_(해시) | S_1 ... S_N N - H | 슬라이스(또는 빌더) s_1...s_n 의 연결 해시를 계산하여 반환합니다. |
해시_(해시) | S_N ... S_1 N - H | 동일하지만 인수가 역순으로 주어집니다. |
해시_(해시) | b s_1 ... s_n n - b' | 결과 해시를 스택에 푸시하는 대신 빌더 b 에 추가합니다. |
해시_(해시) | b s_n ... s_1 n - b' | 인수는 역순으로 주어지며 빌더에 해시를 추가합니다. |
루트 셀의 s_i
비트만 사용됩니다.
각 청크 s_i
는 정수가 아닌 바이트 수를 포함할 수 있습니다. 하지만 모든 청크의 비트 합은 8로 나눌 수 있어야 합니다.
TON은 최상위 비트 순서를 사용하므로 바이트 수가 정수가 아닌 두 슬라이스가 연결되면 첫 번째 슬라이스의 비트가 최상위 비트가 된다는 점에 유의하세요.
가스 소비량은 해시된 바이트 수와 선택한 알고리즘에 따라 달라집니다. 청크당 가스 단위 1개가 추가로 소비됩니다.
A]`를 활성화하지 않으면 해싱 결과가 256비트에 맞으면 부호 없는 정수로, 그렇지 않으면 정수 튜플로 반환됩니다.
다음 알고리즘을 사용할 수 있습니다:
- 'SHA256` - openssl 구현, 바이트당 1/33 가스, 해시는 256비트입니다.
- 'SHA512` - openssl 구현, 바이트당 1/16 가스, 해시는 512비트입니다.
- 'BLAKE2B` - openssl 구현, 바이트당 1/19 가스, 해시는 512비트입니다.
- 'KECCAK256` - 이더리움 호환 구현, 바이트당 1/11 가스, 해시는 256비트입니다.
- 'KECCAK512` - 이더리움 호환 구현, 바이트당 1/6 가스, 해시는 512비트입니다.
가스 사용량은 반올림됩니다.
암호화
현재 사용 가능한 유일한 암호화 알고리즘은 'CHKSIGN'입니다. 공개 키 'k'에 대한 해시 'h'의 Ed25519 서명을 확인하는 것입니다.
- 비트코인 및 이더리움과 같은 이전 세대 블록체인과의 호환성을 위해 'secp256k1' 서명도 확인해야 합니다.
- 최신 암호화 알고리즘의 경우 곡선 덧셈과 곱셈이 최소한의 기능입니다.
- 이더리움 2.0 지분 증명 및 기타 최신 암호화 방식과의 호환성을 위해서는 bls12-381 커브의 BLS 서명 체계가 필요합니다.
- 일부 보안 하드웨어의 경우 secp256r1 == P256 == prime256v1이 필요합니다.
secp256k1
비트코인/이더리움 서명. libsecp256k1 구현](https://github.com/bitcoin-core/secp256k1) 사용.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxx 설명 |
---|---|---|
ECRECOVER | 해시 V R S - 0 또는 H X1 X2 -1 | 비트코인/이더리움 연산과 동일하게 서명에서 공개키를 복구합니다. 32바이트 해시를 uint256 해시 로, 65바이트 서명을 uint8 v 와 uint256 r , s 로 받습니다.실패 시 0 , 성공 시 공개키와 -1 을 반환합니다.65바이트 공개키는 uint8 h , uint256 x1 , x2 로 반환됩니다.1526 gas. |
secp256r1
OpenSSL 구현을 사용합니다. 인터페이스는 CHKSIGNS
/CHKSIGNU
와 유사합니다. Apple 보안 인클레이브와 호환됩니다.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxx 설명 |
---|---|---|
p256_chksigns | d sig k - ? | 슬라이스 d 와 공개키 k 의 데이터 부분의 seck256r1-서명 sig 를 확인합니다. 성공 시 -1, 실패 시 0을 반환합니다.공개 키는 33바이트 슬라이스(SECG SEC 1의 2.3.4 2항에 따라 인코딩됨)입니다. 서명 sig 는 64바이트 슬라이스(256비트 부호 없는 정수 r 과 s 2개)입니다.3526 gas |
p256_chksignu | h sig k - ? | 동일하지만 부호화된 데이터는 256비트 부호 없는 정수 h 의 32바이트 인코딩입니다.3526 gas |
리스트레토
확장 문서는 여기에 있습니다. 요컨대, Curve25519는 성능을 염두에 두고 개발되었지만 그룹 요소가 여러 개로 표현되는 대칭성을 나타냅니다. 슈노르 서명이나 디피-헬만과 같은 더 간단한 프로토콜은 프로토콜 수준에서 일부 문제를 완화하기 위해 트릭을 적용하지만 키 파생 및 키 블라인드 체계가 깨집니다. 그리고 이러한 트릭은 방탄과 같은 더 복잡한 프로토콜에는 확장되지 않습니다. Ristretto는 대부분의 암호화 프로토콜의 요구 사항인 각 그룹 요소가 고유한 지점에 대응하도록 Curve25519를 산술적으로 추상화한 것입니다. 리스트레토는 본질적으로 필요한 산술적 추상화를 제공하는 Curve25519의 압축/압축 해제 프로토콜입니다. 그 결과, 암호화 프로토콜을 올바르게 작성하기 쉬우면서도 Curve25519의 고성능을 활용할 수 있습니다.
리스트레토 연산을 사용하면 커브25519에서 커브 연산을 계산할 수 있으므로(그 반대는 해당되지 않음), 한 번에 리스트레토와 커브25519 커브 연산을 모두 추가하는 것으로 간주할 수 있습니다.
libsodium 구현이 사용됩니다.
모든 리스트레토-255 포인트는 TVM에서 256비트 부호 없는 정수로 표현됩니다.
인수가 유효한 인코딩된 포인트가 아닌 경우 비정숙 연산은 range_chk
를 반환합니다.
영점은 정수 0
으로 표시됩니다.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxx 설명 |
---|---|---|
rist255_fromhash | H1 H2 - X | 결정론적으로 512비트 해시(256비트 정수 두 개로 제공)에서 유효한 점 x 를 생성합니다.626 gas |
rist255_validate | x - | 정수 x 가 어떤 커브 포인트의 유효한 표현인지 확인합니다. 오류 시 range_chk 를 반환합니다.226 gas |
RIST255_ADD | X Y - X+Y | 커브에 두 점 추가. 626 gas |
RIST255_SUB | 엑스 와이 - 엑스 와이 | 곡선에서 두 점 빼기. 626 gas |
RIST255_MUL | `X N - XN`* | 포인트 x 에 스칼라 n 을 곱합니다.음수를 포함한 모든 n 이 유효합니다.2026 gas. |
rist255_mulbase | `n - gn`* | 제너레이터 포인트 g 에 스칼라 n 을 곱합니다.음수를 포함한 모든 n 이 유효합니다.776 gas |
rist255_pushl | - l | 그룹의 순서인 정수 l=2^252+27742317777372353535851937790883648493 을 푸시합니다.26 gas |
rist255_qvalidate | x - 0 또는 -1 | 234 gas의 조용한 버전입니다. |
RIST255_QADD | x y - 0 또는 x+y -1 | RIST255_ADD`의 조용한 버전. 634 gas |
RIST255_QSUB | x y - 0 또는 x-y -1 | 조용한 버전의 RIST255_SUB .634 gas |
RIST255_QMUL | `x n - 0 또는 xn -1`* | 조용한 버전의 RIST255_MUL .2034 gas |
rist255_qmulbase | `N - 0 또는 GN -1`* | 784 gas의 조용한 버전입니다. |
BLS12-381
페어링 친화적인 BLS12-381 커브에 대한 연산. BLST 구현이 사용됩니다. 또한 이 커브를 기반으로 하는 BLS 서명 체계에 대한 연산도 사용됩니다.
BLS 값은 다음과 같은 방식으로 TVM에 표시됩니다:
- G1 포인트 및 공개 키: 48바이트 슬라이스.
- G2 포인트 및 서명: 96바이트 슬라이스.
- 필드 FP의 요소: 48바이트 슬라이스.
- 필드 FP2의 요소: 96바이트 슬라이스.
- 메시지: 슬라이스. 비트 수는 8로 나눌 수 있어야 합니다.
입력 값이 점 또는 필드 요소인 경우 슬라이스는 48/96바이트를 초과할 수 있습니다. 이 경우 처음 48/96바이트만 가져옵니다. 슬라이스의 바이트 수가 이보다 적거나 메시지 크기를 8로 나눌 수 없는 경우 셀 언더플로 예외가 발생합니다.
높은 수준의 작업
이는 BLS 서명을 확인하기 위한 높은 수준의 작업입니다.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxx 설명 |
---|---|---|
BLS_VERIFY | pk msg sgn - bool | BLS 서명을 확인하여 성공 시 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. 61034 gas |
bls_aggregate | sig_1 ... sig_n n - sig | 서명을 집계합니다. n>0 . n=0또는 일부 sigi`가 유효한 서명이 아닌 경우 예외를 던집니다.gas=n\*4350-2616\ _. |
bls_fastaggregate 무엇이든ify - | pk_1 ... pk_n n msg sig - bool | 키 pk_1...pk_n 과 메시지 msg 에 대해 집계된 BLS 서명을 확인합니다. 성공하면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. n=0이면 false를 반환합니다.<br/>_ gas=58034+n*3000`_ |
bls_aggregate 무엇이든ify | pk_1 msg_1 ... pk_n msg_n n sgn - bool | 키-메시지 쌍 pk_1 msg_1...pk_n msg_n 에 대해 집계된 BLS 서명을 확인합니다. 성공하면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. n=0이면 false를 반환합니다.<br/>_ gas=38534+n*22500`_ |
'검증' 명령은 유효하지 않은 서명 및 공개 키에 대해 예외를 발생시키지 않으며(셀 언더플로 예외 제외), 대신 거짓을 반환합니다.
저수준 작업
그룹 요소에 대한 산술 연산입니다.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxxxx 설명 |
---|---|---|
BLS_G1_ADD | X Y - X+Y | G1에 추가. 3934 gas |
BLS_G1_SUB | 엑스 와이 - 엑스 와이 | G1에서 빼기. 3934 gas |
BLS_G1_NEG | x - -x | 784 gas에서 부정. |
BLS_G1_MUL | `X S - XS`* | G1 포인트 x 에 스칼라 s 를 곱합니다.음수를 포함한 모든 s 가 유효합니다.5234 gas |
BLS_G1_멀티엑스피 | `X_1 S_1 ... X_N S_N N - X_1S_1+...+X_NS_N` | G1 포인트 x_i 와 스칼라 s_i 에 대해 x_1*s_1+...+x_n*s_n 을 계산합니다. n=0이면 영점을 반환합니다.<br/>음수를 포함한 모든 si`가 유효합니다.gas=11409+n\*630+n/floor(max(log2(n),4))\*8820\ _ |
BLS_G1_ZERO | - 0 | G1의 영점을 푸시합니다. 34 gas |
BLS_MAP_TO_G1 | f - x | FP 요소 f 를 G1 포인트로 변환합니다.2384 gas |
BLS_G1_INGGROUP | x - bool | 슬라이스 x 가 G1의 유효한 요소를 나타내는지 확인합니다.2984 gas |
BLS_G1_ISZERO | x - bool | G1 포인트 x 가 0과 같은지 확인합니다.34 gas |
BLS_G2_ADD | X Y - X+Y | G2에 추가. 6134 gas |
BLS_G2_SUB | 엑스 와이 - 엑스 와이 | 6134 gas에서 뺄셈. |
BLS_G2_NEG | x - -x | 1584 gas에서 부정. |
BLS_G2_MUL | `X S - XS`* | G2 포인트 x 에 스칼라 s 를 곱합니다.음수를 포함한 모든 s 가 유효합니다.10584 gas |
BLS_G2_멀티엑스피 | `X_1 S_1 ... X_N S_N N - X_1S_1+...+X_NS_N` | G2 포인트 x_i 와 스칼라 s_i 에 대해 x_1*s_1+...+x_n*s_n 을 계산합니다. n=0이면 영점을 반환합니다.<br/>음수를 포함한 모든 si`가 유효합니다.gas=30422+n\*1280+n/floor(max(log2(n),4))\*22840\ _ |
BLS_G2_ZERO | - 0 | G2에서 영점을 푸시합니다. 34 gas |
BLS_MAP_TO_G2 | f - x | FP2 요소 f 를 G2 포인트로 변환합니다.7984 gas |
'bls_g2_ingroup' | x - bool | 슬라이스 x 가 G2의 유효한 요소를 나타내는지 확인합니다.4284 gas |
BLS_G2_ISZERO | x - bool | G2 포인트 x 가 0인지 확인합니다.34 gas |
BLS_PAIRING | x_1 y_1 ... x_n y_n n - bool | G1 점 x_i 와 G2 점 y_i 가 주어지면, x_i,y_i 의 쌍을 계산하고 곱합니다. 결과가 FP12의 곱셈 동일성이면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. n=0이면 false를 반환합니다.<br/>_ gas=20034+n*11800`_ |
BLS_PUSHR | - r | G1과 G2(약 2^255 )의 순서를 푸시합니다.34 gas |
INGROUP,
ISZERO`는 유효하지 않은 점(셀 언더플로 예외 제외)에 대해 예외를 던지지 않고 대신 false를 반환합니다.
다른 산술 연산은 유효하지 않은 커브 점에 대해 예외를 발생시킵니다. 주어진 커브 점이 G1/G2 그룹에 속하는지 확인하지 않는다는 점에 유의하십시오. 이를 확인하려면 INGROUP
명령을 사용하십시오.
RUNVM
현재 TVM의 코드가 외부의 신뢰할 수 없는 코드를 "샌드박스에서" 호출할 수 있는 방법은 없습니다. 즉, 외부 코드는 항상 코드, 컨트랙트 데이터 또는 설정된 작업(예: 모든 송금)을 비가역적으로 업데이트할 수 있습니다.
런브엠명령어를 사용하면 호출자의 상태를 오염시킬 위험 없이 독립적인 VM 인스턴스를 생성하고 원하는 코드를 실행하여 필요한 데이터(스택, 레지스터, 가스 소비량 등)를 얻을 수 있습니다. 임의의 코드를 안전한 방식으로 실행하는 것은 [v4 스타일 플러그인](/participate/wallets/contracts#wallet-v4), Tact의
init` 스타일 하청 계약 계산 등에 유용할 수 있습니다.
xxxxxxxxxxx 파이브 구문 | xxxxxxxxxxxxxxx 스택 | xxxxxxxxxxxxxxxxxx 설명 |
---|---|---|
flags RUNVM | X_1 ... X_N N 코드 [R] [C4] [C7] [G_L] [G_M] - X'_1 ... X'_M 종료코드 [데이터'] [C4'] [C5] [G_C] | 코드 code 와 스택 x_1...x_n 으로 자식 VM을 실행합니다. 결과 스택 x'_1...x'_m 과 종료 코드를 반환합니다.다른 인자와 반환 값은 플래그를 통해 활성화할 수 있습니다(아래 참조). |
RUNVMX | X_1 ... X_N N 코드 [R] [C4] [C7] [G_L] [G_M] 플래그 - X'_1 ... X'_M 종료 코드 [데이터'] [C4'] [C5] [G_C] | 같은 기능이지만 스택에서 플래그를 팝업합니다. |
플래그는 파이브의 runvmx
와 유사합니다:
+1
: C3를 코드로 설정- 2`: 코드를 실행하기 전에 암시적 0을 푸시합니다.
- 4
: 스택(퍼시스턴트 데이터)에서
c4`를 가져와 최종 값을 반환합니다. - 8
: 스택에서 가스 한도
g_l을 가져오고, 소비된 가스
g_c`를 반환합니다. - 16
: 스택에서
c7`을 가져옵니다 (스마트 컨트랙트 컨텍스트). - 32
:
c5`의 최종 값 반환(액션) - 64
: 스택에서 하드 가스 제한(ACCEPT로 활성화)
g_m`을 팝합니다. +128
: "격리된 가스 소비". 하위 VM에는 별도의 방문 셀 세트와 별도의 chksgn 카운터가 있습니다.- 256
: 정수
r을 팝하고 스택 상단에서 정확히
r값을 반환합니다(
exitcode=0 또는 1인 경우에만, 충분하지 않으면
exitcode=stk_und`).
가스 비용:
- 66 가스
- 하위 VM에 제공되는 모든 스택 요소당 가스 1개(처음 32개는 무료)
- 하위 VM에서 반환된 모든 스택 요소당 가스 1개(처음 32개는 무료)
메시지 보내기
현재 컨트랙트에서 메시지 전송 비용을 계산하는 것은 어렵고(jettons에서와 같이 근사치를 구할 수 있음), 액션 단계가 잘못된 경우 요청을 반송하는 것도 불가능합니다. 또한 수신 메시지에서 '컨트랙트 로직에 대한 상수 수수료'와 '가스 비용'의 합계를 정확하게 빼는 것도 불가능합니다.
- SENDMSG
는 셀과 모드를 입력으로 받습니다. 출력 액션을 생성하고 메시지 생성에 대한 수수료를 반환합니다. 모드는 SENDRAWMSG의 경우와 동일한 효과를 갖습니다. 추가로
+1024는 액션을 만들지 않고 수수료만 추정한다는 의미입니다. 다른 모드는 다음과 같이 수수료 계산에 영향을 줍니다: 64
는 들어오는 메시지의 전체 잔액을 나가는 값으로 대체(약간 부정확, 계산 완료 전에 추정할 수 없는 가스비는 고려되지 않음),+128
은 계산 단계 시작 전 계약의 전체 잔액 값으로 대체(약간 부정확, 계산 단계 완료 전에 추정할 수 없는 가스비는 고려되지 않음),+1024
는 계산 단계 시작 전의 전체 잔액 값으로 대체합니다. - SENDRAWMSG
,
RAWRESERVE,
SETLIBCODE,
CHANGELIB-
+16플래그가 추가되며, 이는 작업 실패 시 트랜잭션을 바운스한다는 의미입니다. 2
를 사용하면 효과가 없습니다.