본문으로 건너뛰기

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개 가스, PREVMCBLOCKSPREVKEYBLOCK(34개 가스)을 제외합니다.

xxxxxxxxxxxxxxxxxx
다섯 번째 구문
xxxxxxxxx
스택
xxxxxxxxxxxxxxxxxxxxxxxxxxx
설명
MYCODE- cc7에서 스마트 컨트랙트 코드를 검색합니다.
'들어오는 값'- tc7에서 수신 메시지 값을 검색합니다.
스토리지- ic7에서 스토리지 단계 수수료의 가치를 검색합니다.
'이전블록인포튜플'- tc7에서 PrevBlocksInfo: [last_mc_블록, prev_key_블록]을 가져옵니다.
PREVMC블록- t마지막mc블록`만 검색합니다.
'이전 키 블록'- t이전블록`만 검색합니다.
GLOBALID- i19개 네트워크 구성에서 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
muladddivmodrx y w z - q=라운드((xy+w)/z) r=(xy+w)-zq
muladddivmodcx y w z - q=ceil((xy+w)/z) r=(xy+w)-zq
ADDDIVMODx w z - q=floor((x+w)/z) r=(x+w)-zq
ADDDIVMODRx w z - q=라운드((x+w)/z) r=(x+w)-zq
ADDDIVMODCX 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)입니다(현재 arg1arg2`가 모두 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_chksignsd sig k - ?슬라이스 d와 공개키 k의 데이터 부분의 seck256r1-서명 sig를 확인합니다. 성공 시 -1, 실패 시 0을 반환합니다.
공개 키는 33바이트 슬라이스(SECG SEC 1의 2.3.4 2항에 따라 인코딩됨)입니다.
서명 sig는 64바이트 슬라이스(256비트 부호 없는 정수 rs 2개)입니다.
3526 gas
p256_chksignuh 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_fromhashH1 H2 - X결정론적으로 512비트 해시(256비트 정수 두 개로 제공)에서 유효한 점 x를 생성합니다.
626 gas
rist255_validatex -정수 x가 어떤 커브 포인트의 유효한 표현인지 확인합니다. 오류 시 range_chk를 반환합니다.
226 gas
RIST255_ADDX 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_qvalidatex - 0 또는 -1
234 gas의 조용한 버전입니다.
RIST255_QADDx y - 0 또는 x+y -1RIST255_ADD`의 조용한 버전.
634 gas
RIST255_QSUBx 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_VERIFYpk msg sgn - boolBLS 서명을 확인하여 성공 시 참을 반환하고, 그렇지 않으면 거짓을 반환합니다.
61034 gas
bls_aggregatesig_1 ... sig_n n - sig서명을 집계합니다. n>0. n=0또는 일부sigi`가 유효한 서명이 아닌 경우 예외를 던집니다.
gas=n\*4350-2616\_.
bls_fastaggregate 무엇이든ify-pk_1 ... pk_n n msg sig - boolpk_1...pk_n과 메시지 msg에 대해 집계된 BLS 서명을 확인합니다. 성공하면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. n=0이면 false를 반환합니다.<br/>_gas=58034+n*3000`_
bls_aggregate 무엇이든ifypk_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_ADDX Y - X+YG1에 추가.
3934 gas
BLS_G1_SUB엑스 와이 - 엑스 와이G1에서 빼기.
3934 gas
BLS_G1_NEGx - -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- 0G1의 영점을 푸시합니다.
34 gas
BLS_MAP_TO_G1f - xFP 요소 f를 G1 포인트로 변환합니다.
2384 gas
BLS_G1_INGGROUPx - bool슬라이스 x가 G1의 유효한 요소를 나타내는지 확인합니다.
2984 gas
BLS_G1_ISZEROx - boolG1 포인트 x가 0과 같은지 확인합니다.
34 gas
BLS_G2_ADDX Y - X+YG2에 추가.
6134 gas
BLS_G2_SUB엑스 와이 - 엑스 와이
6134 gas에서 뺄셈.
BLS_G2_NEGx - -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- 0G2에서 영점을 푸시합니다.
34 gas
BLS_MAP_TO_G2f - xFP2 요소 f를 G2 포인트로 변환합니다.
7984 gas
'bls_g2_ingroup'x - bool슬라이스 x가 G2의 유효한 요소를 나타내는지 확인합니다.
4284 gas
BLS_G2_ISZEROx - boolG2 포인트 x가 0인지 확인합니다.
34 gas
BLS_PAIRINGx_1 y_1 ... x_n y_n n - boolG1 점 x_i와 G2 점 y_i가 주어지면, x_i,y_i의 쌍을 계산하고 곱합니다. 결과가 FP12의 곱셈 동일성이면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. n=0이면 false를 반환합니다.<br/>_gas=20034+n*11800`_
BLS_PUSHR- rG1과 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 RUNVMX_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과 종료 코드를 반환합니다.
다른 인자와 반환 값은 플래그를 통해 활성화할 수 있습니다(아래 참조).
RUNVMXX_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를 사용하면 효과가 없습니다.