Web2와 Web3를 구별하려고 할 때 둘을 구별하는 핵심 가치는 소유권의 개념입니다.
간단히 말해서, 당신이 만드는 것은 당신이 소유하고 수익을 창출할 수 있는 것입니다. 그래야만합니다. 그 이상도 그 이하도 아닙니다. 실제로 첫 번째 NFT를 만드는 날은 블록체인의 불변성 덕분에 Web3에서 소유자로서 NFT를 만든 날입니다. 오히려 보호받고 있다는 느낌은 매우 귀중합니다.
말하자면, 이러한 소유권 개념은 접근 가능한 기능 및 허용된 상태 변경과 관련하여 스마트 계약에 있어서 중요합니다.
그렇다면 귀하가 작성한 스마트 계약을 '소유'하는 것이 왜 중요한가요?
생각해 보십시오. 자전거를 소유하고 있다면 소유권 기록을 보관하는 것을 주저하시겠습니까? 누군가가 그것을 훔쳐서 사악한 목적으로 사용한 경우를 대비해서요? 당연히 아니지.
NFT나 스마트 계약의 소유권을 증명하려는 이유도 마찬가지입니다. 글쎄요, 누군가가 무단 액세스를 얻어 금전적인 이익을 얻을 수도 있습니다. 그렇죠?
당신이 Dunzo와 함께 일하고 구매자가 지불했는지 여부와 함께 패키지 가격과 배송비를 설정할 수 있는 스마트 계약을 작성했다고 가정해 보겠습니다.
이상적인 시나리오에서는 구매자 이름, 패키지 및 배송의 총 가격을 특정 금액으로 설정하고 setPackageDelivered를 true로 설정할 수 있습니다. 물론 패키지 배송이 완료되면 말이죠.
그러나 우리 모두 알고 있듯이 계획대로 되는 것은 아무것도 없습니다.
이제 구매자가 계약 기능에 액세스할 수 있고 packageDelivered 값을 false로 재설정하거나 packageDeliveryPrice 값을 더 낮은 값으로 변경할 수 있다면 어떻게 될까요? 그들은 제품에 대해 더 적은 비용을 지불할 수 있을 뿐만 아니라 전혀 비용을 지불하지 않고도 벗어날 수 있습니다.
분명히 Dunzo 외에는 누구도 그러한 변경을 수행할 수 있는 액세스 권한을 가져서는 안 되며, 이것이 바로 액세스 제어 설정이 중요한 이유입니다.
이제 이 스마트 계약을 배포하고 침입자가 상태 변수의 값을 변경하는 것이 얼마나 쉬운지 살펴보겠습니다.
setPrice 및 setPackageDelivered 기능에 모두 액세스할 수 있으므로 누구나 Dunzo 배송에 재정적 손실을 초래할 수 있는 변경 작업을 수행할 수 있습니다.
Dunzo가 항목의 원래 가격을 5 ETH로 설정한 경우 고객은 이제 해당 값을 3 ETH로 변경할 수 있습니다. 물론 고객은 setPackageDelivered 함수에 액세스하여 부울 값을 false로 변경할 수도 있으므로 동일한 품목을 다시 배송받을 수도 있습니다. 따라서 두 경우 모두 Dunzo는 돈을 잃을 것이며 너무 늦을 때까지 그것을 깨닫지 못할 수도 있습니다.
예를 들어, 아래와 같이 배송되는 제품의 가치가 5 ETH라고 가정해 보겠습니다.
배포 시 Dunzo 외에는 누구도 계약 조건을 수정할 수 없어야 합니다. 하지만 Remix에서 주소를 전환하고 가격을 3으로 재설정하면 보호 기능이 없기 때문에 이것이 가능합니다.
setPackageDelivered 상태를 true에서 false로 변경할 수도 있습니다. 패키지가 이미 고객에게 배송된 경우에도 마찬가지입니다.
알 수 있듯이 해당 스마트 계약의 소유자와 다른 사용자를 구별하는 것이 중요합니다. 따라서 이 스마트 계약에 대한 적절한 액세스 제어를 설정하고 결과적으로 안전을 보장하는 4가지 수정 사항을 살펴보겠습니다.
그렇다면 스마트 계약을 작성할 때 소유자와 다른 사용자를 어떻게 구별할 수 있습니까?
무시할 경우 발생할 수 있는 금전적 손실 때문에 이는 분명히 필요한 일입니다.
방법 #1: require 문을 사용하세요
아래 코드에서 볼 수 있듯이 주소 유형의 새로운 상태 변수 소유자가 'require' 문과 함께 추가되었습니다. 생성자에서 소유자 상태 변수는 계약을 배포할 때 사용되는 주소를 저장합니다. 아시다시피 스마트 계약의 생성자는 한 번만 호출되므로 주소를 변경할 수 없습니다.
이제 더 작은 값과 다른 주소로 setPrice 함수를 호출하면 아래 메시지와 같이 트랜잭션이 초기 상태로 되돌아갑니다.
보시다시피 계약서에 제공된 이유는 'require' 문에 추가한 오류 메시지와 관련이 있습니다. 즉, 계약 소유자(이 경우 Dunzo) 외에는 누구도 판매 조건을 변경할 수 없습니다.
방법 #2: 함수 수정자 사용
올바른 조건으로 'require' 문을 추가하는 것만큼 간단한 수정자는 반복적으로 사용할 수 있는 코드 블록입니다. 이는 확실히 그러한 수표에 대해 수많은 '요구' 문을 작성하는 것보다 훨씬 더 의미가 있습니다.
이전에 공유한 코드에서는 setPrice 함수만 'require' 문으로 보호되지만 여기에서는 setPackageDelivered 함수에 대해 아무 작업도 수행되지 않았습니다. 아래 Solidity 코드에 표시된 대로 수정자를 사용하면 트릭을 수행할 수 있습니다.
이제 setPrice 또는 setPackageDelivered 함수에 액세스하려고 하면 앞서 얻은 것과 동일한 오류 메시지가 아래와 같이 표시됩니다.
방법 #3: 소유 가능
이 수정 사항을 적용하려면 OpenZeppelin에서 제공하는 소유 가능 스마트 계약을 사용해야 합니다. 먼저, 소유 가능한 스마트 계약을 가져온 다음 보호하려는 기능에 onlyOwner 수정자를 추가해야 합니다. 따라서 아래와 같이 setPrice 및 setPackageDelivered 함수에는 아래의 onlyOwner 수정자가 있습니다.
이제 dunzoDelivery 스마트 계약은 Ownable.sol의 일부 기능을 사용하므로 "is Ownable"도 계약 이름에 추가됩니다.
즉, 소유 가능 스마트 계약을 사용할 때 액세스할 수 있는 두 가지 다른 기능인 renounceOwnership 및 transferOwnership이 있습니다. 일반적으로 계약을 배포하는 데 사용된 계정이 소유자로 간주되지만 이러한 기능을 사용하여 이를 변경할 수 있습니다.
소유자의 주소 및 기타 계약 세부정보를 보는 것 외에도 아래에서 사용할 수 있는 renounceOwnership 및 transferOwnership 함수를 볼 수 있습니다.
예상대로 다른 주소를 사용하여 setPrice 함수를 호출하려고 하면 트랜잭션이 진행되지 않습니다. 대신 아래와 같은 이유에 따라 원래 상태로 되돌아갑니다.
다른 사용자들 사이에 단일 소유자만 필요한 경우 소유 가능 스마트 계약을 사용하는 것이 좋습니다. 더 많은 계층 구조를 찾고 있다면 AccessControl.sol 스마트 계약을 사용해야 합니다.
방법 #4: 접근 제어
이 마지막 수정을 위해서는 Open Zeppelin을 통해 AccessControl 스마트 계약에 액세스해야 합니다.
우선, import 문에 액세스 제어 하이퍼링크를 추가하고 계약 문에 "is AccessControl"을 추가해야 합니다.
앞에서 언급했듯이 이 스마트 계약을 사용하면 아래 표시된 스마트 계약의 처음 두 줄과 같이 계층 구조 내에 선언해야 하는 여러 역할을 추가할 수 있습니다.
이 계약에는 Dunzo와 Customer라는 두 가지 역할이 있습니다. 이제 계약을 배포할 때 앞서 선언된 역할을 해당 주소에 할당하여 누가 무엇에 액세스할 수 있는지 결정해야 합니다. 또한 setPrice 및 setPackageDelivered 함수에 두 개의 'require' 문이 추가되었습니다.
아시다시피 Dunzo 역할이 할당된 계정만 배포 시 언급된 판매 조건을 변경할 수 있으며 다른 어떤 것도 변경할 수 없습니다. 즉, AccessControl.sol을 사용하여 스마트 계약 기능에 대한 액세스 수준이 서로 다른 여러 역할을 할당할 수 있지만 Ownable.sol은 그다지 깊이 들어가지 않습니다.
이제 스마트 계약에서 액세스 제어를 구현하는 데 사용할 수 있는 유일한 솔루션은 아닙니다. RBAC.sol 및 WhitelistCrowdSale.sol 도 과거에 사용 가능했으며 AccessControl.sol 및 Ownable.sol과 마찬가지로 역할을 주소와 연결할 수도 있습니다.
따라서 액세스 제어 구현의 발전 과정을 철저하게 이해하고 싶다면 이 두 가지 스마트 계약의 코드도 살펴보는 것이 시간을 투자할 가치가 있을 것입니다.
여기에도 게시되었습니다 .
이 기사의 리드 이미지는 "액세스 거부 생체 인식 스캔" 프롬프트를 통해HackerNoon의 AI 이미지 생성기 에 의해 생성되었습니다.