payable
payable 함수는 이더를 받을 수 있게하는 특별한 함수 유형.
일반적인 웹 서버에서 API 함수를 실행할 때에는, 우리는 함수 호출을 통해서 US 달러를 보낼 수 없다. 물론 비트코인도.
하지만 이더리움에서는, 돈(이더), 데이터(transaction payload), 그리고 컨트랙트 코드 자체 모두 이더리움 위에 존재하기 때문에, 우리가 함수를 실행하는 동시에 컨트랙트에 돈을 지불하는 것이 가능하다.
contract OnlineStore {
function buySomething() external payable {
// 함수 실행에 0.001이더가 보내졌는지 확실히 하기 위해 확인:
require(msg.value == 0.001 ether);
// 보내졌다면, 함수를 호출한 자에게 디지털 아이템을 전달하기 위한 내용 구성:
transferThing(msg.sender);
}
}
여기서, msg.value는 컨트랙트로 이더가 얼마나 보내졌는지 확인하는 방법.
컨트랙트에서 이더를 꺼내는 방법
contract GetPaid is Ownable {
function withdraw() external onlyOwner {
owner.transfer(this.balance);
}
}
this.balance는 컨트랙트에 저장돼있는 전체 잔액을 반환
한 가지 활용법으로는 구매자와 판매자가 존재하는 컨트랙트에서, 판매자의 주소를 storage에 저장하고, 누군가 판매자의 아이템을 구매하면 구매자로부터 받은 요금을 그에게 전달할 수도 있다
seller.transfer(msg.value)
난수
keccak256을 통해 난수를 만들수있지만 이 방법은 정직하지 않은 노드의 공격에 취약하다.
우리가 이더리움에서 컨트랙트의 함수를 실행하게되면 이를 하나의 트랜잭션(transaction)으로서 네트워크의 노드 하나 혹은 여러 노드에 실행을 알리게 된다. 그 후 네트워크의 노드들은 여러 개의 트랜잭션을 모으고, "작업 증명"으로 알려진 계산이 매우 복잡한 수학적 문제를 먼저 풀기 위한 시도를 하게 된다. 그리고서 해당 트랜잭션 그룹을 그들의 작업 증명(PoW)과 함께 블록으로 네트워크에 배포하게 된다.
이것이 우리의 난수 함수를 취약하게 만든다
내가 만약 노드를 실행하고 있다면, 나는 오직 나의 노드에만 트랜잭션을 알리고 이것을 공유하지 않을 수 있다.
우리가 동전 던지기 컨트랙트를 사용한다고 할 때 해보자. 내가 동전을 던져서 당첨이 되지 않았다면 내가 풀고 있는 다음 블록에 해당 트랜잭션을 포함하지 않을 수 있다. 당첨이 된 경우에만 선택적으로 트랜잭션을 다음 블록에 추가시키면 된다.
이 짓을 무한대로 반복할 수 있기에 문제.
개선하는 방법은 oracle(이더리움 외부에서 데이터를 받아오는 안전한 방법 중 하나)을 사용해서 블록체인 밖에서 안전한 난수를 만드는 방법
https://cryptozombies.io/ko/course
'Block Chain' 카테고리의 다른 글
[BlockChain] 크립토좀비 레슨5 (0) | 2023.02.28 |
---|---|
[BlockChain] 크립토좀비 레슨3 (0) | 2023.02.13 |
[BlockChain] 크립토좀비 레슨2 (0) | 2023.02.11 |
[BlockChain] 크립토좀비 레슨1 (0) | 2023.02.10 |
[BlockChain] Move 언어 (0) | 2023.02.03 |