> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/blockchain/scene-blockchain-operations.md).

# 씬 블록체인 작업

Ethereum 블록체인에서 작업을 수행하기 위해 SDK가 제공하는 기능을 알아봅니다

Decentraland 씬은 Ethereum 블록체인과 인터페이스할 수 있습니다. 이를 통해 사용자의 지갑과 그 안의 토큰에 대한 데이터를 가져오거나, 대체 가능하거나 대체 불가능한 모든 Ethereum 토큰과 관련될 수 있는 트랜잭션을 트리거할 수 있습니다. 이는 예를 들어 토큰을 판매하거나, 게임 메커니즘의 일부로 토큰을 보상으로 지급하거나, 특정 토큰을 소유한 경우 플레이어가 씬과 상호작용하는 방식을 변경하는 등 여러 방식으로 사용할 수 있습니다.

씬에 의해 트리거되는 Ethereum 메인넷의 모든 트랜잭션은 플레이어의 승인과 가스 수수료 지불이 필요합니다.

모든 블록체인 작업도 다음과 같이 수행되어야 합니다. [비동기 함수로](/creator/content-creator-ko/sdk7/programming-patterns/async-functions.md)작성해야 합니다. 타이밍은 외부 이벤트에 따라 달라지기 때문입니다.

## 플레이어의 Ethereum 계정 가져오기

플레이어의 Ethereum 계정을 가져오려면 `getPlayer()` 함수.

```ts
import { getPlayer } from "@dcl/sdk/src/players";

export function main() {
  let userData = getPlayer();
  if (!userData) return;
  if (!userData.isGuest) {
    console.log(userData.userId);
  } else {
    console.log("플레이어가 Web3에 연결되어 있지 않습니다");
  }
}
```

플레이어가 게스트로 Decentraland에 प्रवेश한 경우, 연결된 Ethereum 지갑이 없습니다. 게스트로 연결된 경우, 응답의 `isGuest` 필드가 `getPlayer()` true가 됩니다. 그렇지 않다면, 플레이어의 지갑 주소를 `userId` 필드에서 가져올 수 있습니다. 플레이어로부터 얻을 수 있는 데이터에 대해 자세히 알아보려면 [플레이어 데이터 가져오기](/creator/content-creator-ko/sdk7/interactivity/user-data.md#get-player-data)

{% hint style="warning" %}
**📔 참고**: eth 주소에 대문자가 포함될 수 있지만, 일부 브라우저는 반환된 문자열을 자동으로 소문자로 변환합니다. 주소 값을 비교할 때 모든 브라우저에서 동작하게 하려면 `.toLowerCase()` 메서드를 사용하여 값을 소문자로 변환하세요.
{% endhint %}

## 가스 가격 확인

다음을 가져온 후 `eth-connect` 라이브러리를, 플레이어의 브라우저에서 Web3를 통해 Metamask에 연결할 수 있도록 web3 provider와 request manager를 인스턴스화해야 합니다.

아래 함수는 Ethereum 메인 네트워크의 현재 가스 가격을 가져와 출력합니다.

```ts
import { RequestManager } from "eth-connect";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";

executeTask(async function () {
  // Metamask와 인터페이스하기 위한 web3 provider 인스턴스 생성
  const provider = createEthereumProvider();
  // RPC 메시지의 송수신을 처리할 객체 생성
  const requestManager = new RequestManager(provider);
  // Ethereum 네트워크의 현재 가스 가격 확인
  const gasPrice = await requestManager.eth_gasPrice();
  // 응답 로그
  console.log({ gasPrice });
});
```

{% hint style="info" %}
**💡 팁**: 다음에 의해 처리되는 함수는 `requestManager` 다음을 사용하여 호출해야 합니다. `await`외부 데이터를 가져오는 데 의존하며 완료되기까지 시간이 걸릴 수 있기 때문입니다.
{% endhint %}

## 컨트랙트 ABI 가져오기

ABI(Application Binary Interface)는 Ethereum 컨트랙트와 상호작용하는 방법을 설명하며, 사용 가능한 함수, 입력으로 받는 값, 출력하는 값을 결정합니다. 각 Ethereum 컨트랙트에는 고유한 ABI가 있으므로, 프로젝트에서 사용하려는 모든 컨트랙트의 ABI를 가져와야 합니다.

예를 들어, MANA ABI의 한 함수 예시는 다음과 같습니다.

```ts
{
  anonymous: false,
  inputs: [
    {
      indexed: true,
      name: 'burner',
      type: 'address'
    },
    {
      indexed: false,
      name: 'value',
      type: 'uint256'
    }
  ],
  name: 'Burn',
  type: 'event'
}
```

ABI 정의는 매우 길 수 있는데, 함수가 많이 포함되는 경우가 많기 때문입니다. 따라서 ABI 파일의 JSON 내용을 별도의 `.ts` 파일에 붙여 넣은 다음, 거기서 다른 씬 파일로 import하는 것을 권장합니다. 또한 모든 ABI 파일을 씬의 별도 폴더에 보관하는 것도 권장하며, 폴더 이름은 `/contracts`.

```ts
import { abi } from "../contracts/mana";
```

다양한 Decentraland 컨트랙트에 대한 링크는 다음과 같습니다. 각 컨트랙트의 ABI는 다음을 클릭하여 얻을 수 있습니다. *Export ABI* 를 선택하고 *JSON Format*.

* [MANA Token ABI](https://etherscan.io/address/0x0f5d2fb29fb7d3cfee444a200298f468908cc942#code)
* [Decentraland Marketplace](https://etherscan.io/address/0x19a8ed4860007a66805782ed7e0bed4e44fc6717#code)
* [LAND ABI](https://etherscan.io/address/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d#code)
* [Estate ABI](https://etherscan.io/address/0x959e104e1a4db6317fa58f8295f586e1a978c297#code)
* [AvatarNameRegistry ABI](https://etherscan.io/address/0x894b883905bfEe2CC448880F1b59f4A762E67566)
* [Catalyst ABI](https://etherscan.io/address/0xcc054fab08127c19f621ab83ade5962cd10584ec)

다음은 다양한 웨어러블 컬렉션에 대한 컨트랙트입니다: (각 컬렉션은 별도의 컨트랙트로 배포되었습니다)

* [ExclusiveMasksCollection ABI](https://etherscan.io/address/0xc04528c14c8ffd84c7c1fb6719b4a89853035cdd)
* [Halloween2019Collection ABI](https://etherscan.io/address/0xc1f4b0eea2bd6690930e6c66efd3e197d620b9c2)
* [Halloween2019CollectionFactory ABI](https://etherscan.io/address/0x07ccfd0fbada4ac3c22ecd38037ca5e5c0ad8cfa)
* [Xmas2019Collection ABI](https://etherscan.io/address/0xc3af02c0fd486c8e9da5788b915d6fff3f049866)
* [MCHCollection ABI](https://etherscan.io/address/0xf64dc33a192e056bb5f0e5049356a0498b502d50)
* [CommunityContestCollection ABI](https://etherscan.io/address/0x32b7495895264ac9d0b12d32afd435453458b1c6)
* [DCLLaunchCollection ABI](https://etherscan.io/address/0xd35147be6401dcb20811f2104c33de8e97ed6818)
* [DCGCollection ABI](https://etherscan.io/address/0x3163d2cfee3183f9874e2869942cc62649eeb004)

{% hint style="info" %}
**💡 팁**: 컨트랙트가 노출하는 함수를 명확히 보려면 [abitopic.io](https://abitopic.io)에서 열어보세요. 컨트랙트 주소를 붙여넣고 *functions* 탭을 열면 지원되는 함수와 인자 전체 목록을 볼 수 있습니다. 웹페이지를 통해 다양한 매개변수로 함수 호출을 테스트할 수도 있습니다.
{% endhint %}

JSON 파일에서 import할 수 있도록 TypeScript를 설정하는 것은 어려움이 있습니다. 더 쉽고 권장되는 우회 방법은 `ABI.JSON` 파일 확장자를 `.ts` 로 변경하고, 파일 내용이 다음으로 시작하도록 약간 수정하는 것입니다. `export default`.

예를 들어, ABI 파일의 내용이 다음으로 시작한다면 `[{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`그것을 다음으로 시작하도록 수정하세요. `export default [{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`.

### 컨트랙트 인스턴스화

다음을 가져온 후 `eth-connect` 라이브러리와 컨트랙트의 *abi*를 사용하려면, 컨트랙트의 함수를 사용하고 플레이어의 브라우저에서 Metamask에 연결할 수 있도록 하는 여러 객체를 인스턴스화해야 합니다.

또한 web3 provider를 import해야 합니다. 플레이어의 브라우저에서 Metamask는 web3를 사용하므로, 이를 상호작용할 방법이 필요하기 때문입니다.

```ts
import { RequestManager, ContractFactory } from "eth-connect";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";
import { abi } from "../contracts/mana";

executeTask(async () => {
  // Metamask와 인터페이스하기 위한 web3 provider 인스턴스 생성
  const provider = createEthereumProvider();
  // RPC 메시지의 송수신을 처리할 객체 생성
  const requestManager = new RequestManager(provider);
  // abi를 기반으로 factory 객체 생성
  const factory = new ContractFactory(requestManager, abi);
  // factory 객체를 사용해 특정 컨트랙트를 참조하는 `contract` 객체 인스턴스화
  const contract = (await factory.at(
    "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
  )) as any;
});
```

{% hint style="info" %}
**💡 팁**: ERC20 또는 ERC721과 같은 동일한 표준을 따르는 컨트랙트의 경우, 모두에 대해 하나의 일반 ABI를 import할 수 있습니다. 그런 다음 하나의 `ContractFactory` 객체를 해당 ABI로 생성하고, 동일한 factory를 사용해 각 컨트랙트의 인터페이스를 인스턴스화합니다.
{% endhint %}

### 컨트랙트의 메서드 호출

한 번 `contract` 객체를 생성하면, 지정된 입력 매개변수를 전달하여 ABI에 정의된 함수를 쉽게 호출할 수 있습니다.

```ts
import { getPlayer } from "@dcl/sdk/src/players";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";
import { RequestManager, ContractFactory } from "eth-connect";
import { abi } from "../contracts/mana";

executeTask(async () => {
  try {
    // 위 섹션에서 설명한 설정 단계
    const provider = createEthereumProvider();
    const requestManager = new RequestManager(provider);
    const factory = new ContractFactory(requestManager, abi);
    const contract = (await factory.at(
      "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
    )) as any;
    let userData = getPlayer();
    if (!userData || userData.isGuest) {
      return;
    }

    // 컨트랙트의 함수 수행
    const res = await contract.setBalance(
      "0xaFA48Fad27C7cAB28dC6E970E4BFda7F7c8D60Fb",
      100,
      {
        from: userData.userId,
      }
    );
    // 응답 로그
    console.log(res);
  } catch (error: any) {
    console.log(error.toString());
  }
});
```

위 예시는 *가짜 MANA* 테스트 컨트랙트의 abi를 사용하며, 그 `setBalance` 메서드를 호출해 계정에 100을 부여합니다. *가짜 MANA* 이 예제를 수정할 때는 주소와 abi를 호출하려는 컨트랙트의 것으로 바꾸고, 해당 abi가 정의하는 메서드를 호출하세요.

### 기타 함수

eth-connect 라이브러리에는 사용할 수 있는 다른 헬퍼가 여러 개 포함되어 있습니다. 예를 들어 다음과 같습니다.

* 추정 가스 가격 가져오기
* 지정된 주소의 잔액 가져오기
* 트랜잭션 영수증 가져오기
* 주소에서 보낸 트랜잭션 수 가져오기
* 16진수, 이진수, utf8 등을 포함한 다양한 형식 간 변환

## 이더리움 테스트 네트워크 사용

씬을 테스트할 때 실제 MANA나 다른 통화를 전송하지 않으려면 *Ethereum Sepolia 테스트 네트워크* 를 사용하여 대신 가짜 테스트넷 MANA를 전송할 수 있습니다.

테스트 네트워크를 사용하려면 Metamask Chrome 확장을 다음으로 설정해야 합니다. *Sepolia 테스트 네트워크* 대신 *메인 네트워크*.

Sepolia Ether를 획득해야 하며, 이는 다음과 같은 다양한 외부 faucet에서 무료로 얻을 수 있습니다. [이것](https://www.alchemy.com/faucets/ethereum-sepolia/).

{% hint style="info" %}
**💡 팁**: Sepolia MANA를 지갑으로 전송하는 거래를 실행하려면 Sepolia Ether로 가스비를 지불해야 합니다.
{% endhint %}

테스트 네트워크를 사용하여 장면을 미리 보려면 다음 URL을 브라우저 탭에 붙여넣으세요. 그러면 Decentraland 데스크톱 클라이언트에서 장면이 열립니다:

`decentraland://realm=http://127.0.0.1:8000&local-scene=true&debug=true&dclenv=zone&position=0,0`

{% hint style="info" %}
**💡 팁**: 위치 매개변수를 씬의 좌표로 변경하면 씬으로 직접 로드됩니다..
{% endhint %}

이 모드에서 장면을 보면서 승인한 거래는 테스트 네트워크에서만 발생하며 실제 지갑의 MANA 잔액에는 영향을 주지 않습니다.

Polygon Testnet에서 트랜잭션을 테스트해야 하고 그 테스트넷에 MANA가 필요하다면, Sepolia에서 MANA를 획득한 후 해당 네트워크로 MANA를 스왑해야 합니다. Sepolia MANA를 Polygon Testnet으로 브리지하려면 [Sepolia의 Decentraland 계정 페이지](https://account.decentraland.zone/) 를 방문하여 Ethereum MANA 쪽의 ‘swap’을 클릭하세요.

레거시 웹 클라이언트에서 Ethereum 라이브러리 중 하나를 사용하는 씬의 프리뷰를 실행할 때는, 프리뷰를 별도의 브라우저 창에서 열고 브라우저에서 Metamask를 실행한 상태로, 문자열 `&ENABLE_WEB3`.

## 사용자 정의 RPC 메시지 보내기

다음 함수를 사용하세요. `sendAsync()` 를 사용하여 [RPC 프로토콜](https://en.wikipedia.org/wiki/Remote_procedure_call).

```ts
import { sendAsync } from "~system/EthereumController";

// 메시지 보내기
await sendAsync({
  id: 1,
  method: "myMethod",
  jsonParams: "{ myParam: myValue }",
});
```

## Decentraland 스마트 컨트랙트

다음 링크에서 Decentraland 생태계와 관련된 Etherum 스마트 컨트랙트 목록을 찾을 수 있습니다. 이 목록에는 메인넷의 컨트랙트뿐만 아니라 다른 Ethereum 테스트 네트워크의 컨트랙트도 포함되어 있습니다.

[contracts.decentraland.org](https://contracts.decentraland.org/links)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/blockchain/scene-blockchain-operations.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
