본문으로 건너뛰기

교차 컨트랙트 호출

모든 호출은 독립적이고 비동기적입니다. 다시 말해서:

  • 호출 메서드와 콜백 메서드는 독립적입니다.
  • 호출과 콜백 사이에서 사람들은 컨트랙트와 상호 작용할 수 있습니다.

이는 콜백을 처리하는 방법에 중요한 영향을 미칩니다. 특히:

  1. 콜백 메서드는 공개되어야 하지만, 이를 컨트랙트만 호출할 수 있도록 할 수 있습니다.
  2. 호출과 콜백 사이에 컨트랙트를 악용 가능한 상태로 두지 않아야 합니다.
  3. 외부 호출이 실패한 경우, 콜백의 상태에 대한 모든 변경 사항을 수동으로 롤백해야 합니다.

프라이빗 콜백

교차 컨트랙트 호출이 완료될 때, 컨트랙트가 자체적으로 호출되도록 하려면 콜백 메서드를 공개해야 합니다. 그러나 대부분의 경우 공개되지 않길 원할 것입니다. predecessorcurrent_account임을 assert하여, 메서드를 퍼블릭으로 유지하면서 비공개로 만들 수 있습니다. Rust에서는 #[private] 데코레이터를 추가하면 이 작업이 자동으로 수행됩니다.


사용자의 자금

메서드가 패닉 상태가 되면, 해당 트랜잭션에 첨부된 돈이 predecessor에게 반환됩니다. 즉, 교차 컨트랙트 호출을 하고 실패하면, 돈이 컨트랙트로 돌아갑니다. 컨트랙트를 호출한 사용자로부터 돈이 나온 경우, 콜백 도중에 이를 반환해야 합니다.

img 사용자가 돈을 첨부한 경우, 콜백에서 수동으로 반환해야 합니다

주의

Make sure you pass have enough GAS in the callback to make the transfer


Async Callbacks

교차 컨트랙트 호출과 콜백 사이에서 컨트랙트의 모든 메서드를 실행할 수 있습니다. 이것을 고려하지 않는 것은 해킹의 주요 원인 중 하나입니다. 재진입 공격이라는 자체 이름이 있을 정도로, 이는 매우 기본적인 해킹 방식입니다.

비동기 콜백 다음과 같은 잘못된 로직으로 deposit_and_stake를 개발한다고 상상해 봅시다. (1) 사용자가 우리에게 돈을 보냅니다. (2) 우리는 이를 잔고에 추가합니다. 그러면, 사용자는 (2)와 (4) 사이에 호출을 철회하도록 예약할 수 있으며, 스테이킹에 실패하면 사용자는 두 번 돈을 받게 됩니다.

img 교차 컨트랙트 호출과 콜백 사이에 무슨 일이든 일어날 수 있습니다

다행스럽게도 솔루션은 다소 간단합니다. 사용자의 잔고에 돈을 즉시 추가하는 대신, 콜백이 올 때까지 기다립니다. There we check, and if the staking went well, then we add it to their balance.

img 교차 컨트랙트 호출에서 예금을 처리하는 올바른 방법

Was this page helpful?