ERC-4804 Web3 URL을 EVM 호출로 변환 (Web3 URL to EVM Call Message Translation)

Final · 이름·메타데이터 · 2022-02-14 작성

web3://uniswap.eth/ 같은 웹 주소를 이더리움 컨트랙트 읽기 호출로 바꾸는 규칙입니다. 브라우저 주소처럼 사람이 읽을 수 있는 URL로 온체인 콘텐츠에 바로 닿을 수 있습니다.

왜 필요한가

지금 Web3 의 데이터를 읽는 일은 대부분 Web2 프록시가 블록체인 쪽으로 요청을 바꿔 주는 데 의존합니다. dApp 웹사이트, 노드 서비스 제공자, 이더스캔 같은 중간 서비스가 그 변환을 맡는데, 이들은 사용자의 통제 밖에 있습니다. 체인 위에 SVG 나 HTML 같은 웹 콘텐츠가 저장돼 있어도 일반 사용자가 중간 서비스 없이 바로 꺼내 볼 방법이 없었습니다. 또 웹의 기존 표준들은 URI(자원을 가리키는 주소 문자열)로 대상을 지정하는데, 이더리움 컨트랙트 호출은 16진수 calldata 로 표현되어 둘을 이어 줄 공통 형식이 없었습니다. 이 표준은 web3:// 로 시작하는 주소를 EVM 호출 메시지로 바꾸는 규칙을 정해 Web2 사용자가 Web3 콘텐츠에 직접 닿을 수 있게 하고 URI 를 쓰는 다른 표준과도 서로 통하게 합니다.

심층 설명

Web3 URL 의 구조

Web3 URL 은 web3Schema [userinfo "@"] contractName [":" chainid] path ["?" query] 형태입니다. web3Schema 는 ethereum-web3://, eth-web3://, web3:// 중 하나이며 원문은 web3:// 또는 짧게 w3:// 로 쓴다고 설명합니다. contractName 은 0x 로 시작하는 20바이트 주소이거나 [name "." [subDomain0 "." ...]] nsProviderSuffix 형태의 이름입니다. path 는 ["/" method ["/" argument_0 ["/" argument_1 ...]]] 로 메서드 이름과 인자가 슬래시로 이어지고 각 argument 는 [type "!"] value 로 타입을 앞에 붙일 수 있습니다. query 는 attribute=value 쌍을 & 로 이은 것이며 attribute 로는 returns, returnTypes, 그 밖의 속성이 올 수 있습니다. 이 명세는 Solidity 의 view 함수에 해당하는 읽기 전용 의미만 정의하며 상태를 바꾸는 함수는 나중 확장으로 남겨 두었습니다.

호출 메시지의 From, To, chainid 결정

userinfo 는 EVM 호출 메시지의 From 필드, 즉 누가 호출하는지를 나타냅니다. 지정하지 않으면 발신자 주소로 0x0 을 씁니다. contractName 은 To 필드입니다. 0x 와 20바이트 16진수로 된 주소면 그 값을 To 로 씁니다. 그렇지 않으면 이름 서비스의 이름으로 보고 nsProviderSuffix(예: eth)에 해당하는 제공자에게 주소를 묻습니다. 이름을 주소로 바꾸는 구체적인 방법은 이후 EIP 에서 다룬다고 원문은 밝힙니다. chainid 는 contractName 을 해석하고 메시지를 호출할 체인입니다. 지정하지 않으면 이름 서비스 제공자와 같은 체인을 쓰며 eth 의 경우 1 입니다. 이름 서비스 제공자가 없으면 기본 chainid 는 1 입니다.

resolveMode 와 두 가지 해석 모드

To 주소와 chainid 가 정해지면 프로토콜은 컨트랙트의 resolveMode 메서드를 호출해 해석 모드를 확인합니다. 현재 지원하는 모드는 두 가지입니다. 수동 모드(Manual Mode)는 path 와 query 를 전혀 해석하지 않고 path ["?" query] 문자열을 그대로 메시지의 calldata 로 넣습니다. 컨트랙트가 인코딩 규칙을 직접 정하고 싶을 때 쓰는 방식입니다. 자동 모드(Auto Mode)는 기본 모드이며 대상 컨트랙트에 resolveMode 메서드가 없을 때도 적용됩니다. 자동 모드에서 path 가 비어 있으면 빈 calldata 로 호출하고 그렇지 않으면 표준 Solidity 컨트랙트 ABI 로 calldata 를 만듭니다. method 가 없는 경우, 즉 path 가 비어 있거나 "/" 인 경우에도 빈 calldata 로 호출합니다.

자동 모드의 인자 타입 추론 규칙

자동 모드에서 method 는 호출할 함수 이름 문자열이고 argument_i 는 그 함수의 i 번째 인자입니다. type 을 명시하면 값을 그 타입으로 변환하며 현재 지원하는 기본 타입은 uint256, bytes32, address, bytes, string 입니다. type 을 생략하면 다음 순서로 타입을 자동 감지합니다. 1) 값이 숫자면 uint256, 2) 0x 와 32바이트 16진수 형태면 bytes32, 3) 0x 와 20바이트 16진수 형태면 address, 4) 0x 뒤에 20 또는 32 가 아닌 바이트 수가 오면 bytes, 5) 그 외에는 address 로 보고 값을 [name "." [subDomain0 "." ...]] nsProviderSuffix 형태의 도메인 이름으로 파싱합니다. 5번의 경우 실제 인자 값은 nsProviderSuffix(예: eth)의 이름 서비스에서 얻으며 지원하지 않는 접미사면 unsupported NS provider 오류를 돌려줍니다. 원문은 이 방식을 최대 가능도(maximum likelihood) 원칙이라 부르며 URL 길이를 줄이면서도 혼동이 생기면 명시적 타입으로 해결할 수 있다고 설명합니다.

returns 속성과 반환 데이터 해석

query 의 returns 속성은 반환 데이터를 어떤 형식으로 풀지 알려 줍니다. 지정하지 않으면 반환 데이터를 (bytes32) 로 파싱하고 MIME 타입은 마지막 인자의 접미사(확장자)를 보고 정합니다. returns 가 () 이면 반환 데이터를 원시 바이트(raw bytes) 그대로 JSON 에 담습니다. 그 밖의 값이면 지정한 returns 타입에 맞춰 JSON 으로 파싱합니다. returns 속성이 여러 개 있으면 마지막 것을 적용합니다. returnTypes 는 returns 의 별칭이지만 하위 호환을 위해 남겨 둔 것이므로 사용을 권장하지 않습니다. 예를 들어 balanceOf/vitalik.eth?returns=(uint256) 은 결과를 [ "10000000000000" ] 같은 uint256 값으로, ?returns=() 은 ["0x000000000000000000000000000000000000000000000000000009184e72a000"] 같은 바이트 문자열로 돌려줍니다.

원문 예시로 보는 해석 결과

web3://w3url.eth/ 는 chainid 1(메인넷)의 ENS 에서 w3url.eth 의 주소를 찾아 그 주소를 호출합니다. web3://cyberbrokers-meta.eth/renderBroker/9999 는 같은 방식으로 주소를 찾은 뒤 메서드 이름과 uint256 인자 9999 를 ABI 인코딩한 calldata 로 호출합니다. web3://vitalikblog.eth:5/ 는 chainid 5(Goerli)의 ENS 에서 이름을 찾고 chainid 5 로 호출합니다. web3://0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170/ 처럼 주소를 직접 쓰면 이름 서비스를 거치지 않고 chainid 42170(Arbitrum Nova)에서 빈 calldata 로 호출합니다. web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth 는 인자 vitalik.eth 를 5번 규칙에 따라 chainid 1 의 ENS 에서 주소로 바꾼 뒤 balanceOf(address) 를 호출합니다.

설계 원칙과 적용 범위

원문 Rationale 은 이 제안의 목적을 이더리움에 탈중앙 표현 계층(presentation layer)을 더하는 것으로 설명합니다. HTML, CSS, JPG, PNG, SVG 같은 웹 콘텐츠를 사람이 읽을 수 있는 URL 로 온체인에서 렌더링하고 EVM 을 탈중앙 백엔드로 쓰자는 구상입니다. 설계 원칙은 네 가지입니다. 사람이 읽을 수 있게(Human-readable): http:// 처럼 알아보기 쉽도록 주소 대신 이름 서비스의 이름을, 16진수 calldata 대신 메서드와 인자를 씁니다. HTTP URL 과 최대 호환: 상대 경로, 쿼리, 프래그먼트 등 기존 HTTP URL 표준을 따라 브라우저 등이 작은 수정으로 지원할 수 있게 합니다. 단순함(Simple): 인자 타입 자동 감지로 URL 을 짧게 유지합니다. 유연함(Flexible): 컨트랙트가 인코딩 규칙을 재정의할 수 있게 합니다. 이 표준은 EIP-137 을 전제로 하며(requires: 137), 예시는 모두 ENS 를 이름 서비스로 씁니다. 상태는 Final 입니다.

ERC 원문 · ← ERCs