> For the complete documentation index, see [llms.txt](https://docs.bifrostnetwork.com/kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bifrostnetwork.com/kr/developer-documentations/ethereum-api/ethereum-precompiled-contracts.md).

# 프리컴파일 컨트랙트

바이프로스트 네트워크는 이더리움 메인넷에 배포된 표준 사전 컴파일된 컨트랙트들을 지원합니다. 다음은 구현된 사전 컴파일된 컨트랙트들의 주소 테이블입니다.

#### ECRECOVER

서명이 유효한 경우 ecdsa 서명 (v, r, s)의 서명자 주소를 반환합니다. 솔리디티 코드에서 직접 호출할 수 있습니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000001
function ecrecover(bytes32 data, bytes32 v, bytes32 r, bytes32 s) returns (address);
```

#### SHA256

데이터의 keccak-해시 값을 반환합니다. 솔리디티 코드에서 직접 호출할 수 있습니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000002
function sha256(bytes data) returns (bytes32);
```

#### RIPEMD160

데이터의 ripemd160-해시 값을 반환합니다. 솔리디티 코드에서 직접 호출할 수 있습니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000003
function ripemd160(bytes data) returns (bytes32);
```

#### Identity

데이터 복사 (datacopy)라고도 알려진 이 함수는 메모리에서 데이터를 효율적으로 복사하는 방법을 제공합니다. 솔리디티 컴파일러는 이 함수를 지원하지 않으므로, 이 함수는 다음과 같이 어셈블리 (assembly)를 통해 호출해야 합니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000004
contract Identity{

    bytes public memoryStored;

    function callDatacopy(bytes memory data) public returns (bytes memory) {
        bytes memory result = new bytes(data.length);
        assembly {
            let len := mload(data)
            if iszero(call(gas(), 0x04, 0, add(data, 0x20), len, add(result,0x20), len)) {
                invalid()
            }
        }

        memoryStored = result;

        return result;
    }
}
```

#### Modular Exponentiation

이 함수는 정수 b (밑)를 e승 (지수)한 후 양의 정수 m (모듈러스)으로 나누었을 때의 나머지를 계산합니다. 솔리디티 컴파일러는 이 함수를 지원하지 않으므로, 이 함수는 다음과 같이 어셈블리 (assembly)를 통해 호출해야 합니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000005
contract ModularCheck {

    uint public checkResult;

    // Function to Verify ModExp Result
    function verify( uint _base, uint _exp, uint _modulus) public {
        checkResult = modExp(_base, _exp, _modulus);
    }

    function modExp(uint256 _b, uint256 _e, uint256 _m) public returns (uint256 result) {
        assembly {
            // Free memory pointer
            let pointer := mload(0x40)
            // Define length of base, exponent and modulus. 0x20 == 32 bytes
            mstore(pointer, 0x20)
            mstore(add(pointer, 0x20), 0x20)
            mstore(add(pointer, 0x40), 0x20)
            // Define variables base, exponent and modulus
            mstore(add(pointer, 0x60), _b)
            mstore(add(pointer, 0x80), _e)
            mstore(add(pointer, 0xa0), _m)
            // Store the result
            let value := mload(0xc0)
            // Call the precompiled contract 0x05 = bigModExp
            if iszero(call(not(0), 0x05, 0, pointer, 0xc0, value, 0x20)) {
                revert(0, 0)
            }
            result := mload(value)
        }
    }
}
```

#### BN128Add

`BN128Add` 사전 컴파일 컨트랙트는 네이티브 타원 곡선 점 덧셈을 구현합니다. 이는 (ax, ay)와 (bx, by)가 BN256 곡선 상의 유효한 점일 때, (ax, ay) + (bx, by)를 나타내는 타원 곡선 점을 반환합니다. 솔리디티 컴파일러는 이 함수를 지원하지 않으므로, 이 함수는 다음과 같이 어셈블리 (assembly)를 통해 호출해야 합니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000006
contract Precompiles {
    function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) {
        bytes32[4] memory input;
        input[0] = ax;
        input[1] = ay;
        input[2] = bx;
        input[3] = by;
        assembly {
            let success := call(gas, 0x06, 0, input, 0x80, result, 0x40)
            switch success
            case 0 {
                revert(0,0)
            }
        }
    }
}
```

#### BN128Mul

`BN128Mul` 사전 컴파일 컨트랙트는 스칼라 값과의 네이티브 타원 곡선 곱셈을 구현합니다. 이는 (x, y)가 BN256 곡선 상의 유효한 곡선 점일 때, 스칼라 \* (x, y)를 나타내는 타원 곡선 점을 반환합니다. 솔리디티 컴파일러는 이 함수를 지원하지 않으므로, 이 함수는 다음과 같이 어셈블리 (assembly)를 통해 호출해야 합니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000007
contract Precompiles {
    function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) {
        bytes32[3] memory input;
        input[0] = x;
        input[1] = y;
        input[2] = scalar;
        assembly {
            let success := call(gas, 0x07, 0, input, 0x60, result, 0x40)
            switch success
            case 0 {
                revert(0,0)
            }
        }
    }
}
```

#### BN128Pairing

`BN128Pairing` 사전 컴파일은 zkSNARK 검증을 수행하기 위한 타원 곡선 페어링 (pairing) 연산을 구현합니다. 더 자세한 정보는 [EIP-197](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md) 표준을 확인하세요. 솔리디티 컴파일러는 이 함수를 지원하지 않으므로, 이 함수는 다음과 같이 어셈블리 (assembly)를 통해 호출해야 합니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000008
contract Precompiles {
    function callBn256Pairing(bytes memory input) public returns (bytes32 result) {
        // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k
        uint256 len = input.length;
        require(len % 192 == 0);
        assembly {
            let memPtr := mload(0x40)
            let success := call(gas, 0x08, 0, add(input, 0x20), len, memPtr, 0x20)
            switch success
            case 0 {
                revert(0,0)
            } default {
                result := mload(memPtr)
            }
        }
    }
}
```

#### Blake2F

이 EIP는 `BLAKE2b` 해시 함수 및 다른 상위 라운드 64비트 BLAKE2 변형이 EVM에서 비용 효율적으로 실행될 수 있도록 하여, 이더리움과 Zcash 또는 다른 Equihash 기반 PoW 코인 간의 상호 운용성을 용이하게 합니다. 더 자세한 정보는 [EIP-152 ](https://eips.ethereum.org/EIPS/eip-152)표준을 확인 바랍니다.

```solidity
// contract address: 0x0000000000000000000000000000000000000009
function callBlake2F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, bytes8[2] memory t, bool f) public view returns (bytes32[2] memory) {
    bytes32[2] memory output;

    bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f);

    assembly {
        if iszero(staticcall(not(0), 0x09, add(args, 32), 0xd5, output, 0x40)) {
            revert(0, 0)
        }
    }

    return output;
}
```
