Chainalysis oracle for sanctions screening

The Chainalysis oracle is a smart contract that validates if a cryptocurrency wallet address has been included in a sanctions designation. The smart contract is maintained by Chainalysis on a variety of popular blockchains and will be regularly updated to reflect the latest sanctions designations listed on economic/trade embargo lists from organizations including the US, EU, or UN. The smart contract is available for anyone to use and does not require a customer relationship with Chainalysis.

Defining sanctions data

Sanctioned entities refer to entities listed on economic/trade embargo lists, including but not limited to, sanctions lists imposed by the US, EU, or UN, with which anyone subject to those jurisdictions is prohibited from dealing.

While we will be taking reasonable measures to keep the sanctions oracle up-to-date, Chainalysis cannot guarantee the accuracy, timeliness, suitability, or validity of the data.

Using the Chainalysis oracle

You can use the Chainalysis oracle in conjunction with many programming languages. Below we provide an example for Solidity and for JavaScript using the popular web3.js library.

Solidity

The following code checks whether the address funds are being sent to is on the sanctions list:

1pragma solidity ^0.8.12;
2
3interface SanctionsList {
4 function isSanctioned(address addr) external view returns (bool);
5}
6
7contract ConsumerContract {
8 address constant SANCTIONS_CONTRACT = 0x40C57923924B5c5c5455c48D93317139ADDaC8fb;
9
10 function transfer(address to, uint256 amount) external {
11 SanctionsList sanctionsList = SanctionsList(SANCTIONS_CONTRACT);
12 bool isToSanctioned = sanctionsList.isSanctioned(to);
13 require(!isToSanctioned, "Transfer to sanctioned address");
14 }
15}

JavaScript

The following code checks if an address is on a sanctions list from the web3.js collection of libraries:

1const Web3 = require('web3')
2const rpcurl = "<your web3 provider>"
3const web3 = new Web3(rpcurl)
4const abi = [/* See our ABI below */]
5const contract_address = "0x40c57923924b5c5c5455c48d93317139addac8fb"
6contract = new web3.eth.Contract(abi, contract_address)
7contract.methods.isSanctioned("0x7f268357A8c2552623316e2562D90e642bB538E5").call((err, result) => { console.log("Non-sanctioned address: "); console.log(result); });
8contract.methods.isSanctioned("0x7F367cC41522cE07553e823bf3be79A889DEbe1B").call((err, result) => { console.log("Sanctioned address: "); console.log(result); });

The above code prints:

$Non-sanctioned address:
>false
>Sanctioned address:
>true

Compatible networks

Currently, the Chainalysis oracle is available on the Ethereum network as well as the following EVM-compatible networks (click the links to view the Chainalysis oracle on each network):

Get help

Contact [email protected] to provide feedback or ask us any questions.

ABI

1[
2 {
3 "inputs": [],
4 "stateMutability": "nonpayable",
5 "type": "constructor"
6 },
7 {
8 "anonymous": false,
9 "inputs": [
10 {
11 "indexed": true,
12 "internalType": "address",
13 "name": "addr",
14 "type": "address"
15 }
16 ],
17 "name": "NonSanctionedAddress",
18 "type": "event"
19 },
20 {
21 "anonymous": false,
22 "inputs": [
23 {
24 "indexed": true,
25 "internalType": "address",
26 "name": "previousOwner",
27 "type": "address"
28 },
29 {
30 "indexed": true,
31 "internalType": "address",
32 "name": "newOwner",
33 "type": "address"
34 }
35 ],
36 "name": "OwnershipTransferred",
37 "type": "event"
38 },
39 {
40 "anonymous": false,
41 "inputs": [
42 {
43 "indexed": true,
44 "internalType": "address",
45 "name": "addr",
46 "type": "address"
47 }
48 ],
49 "name": "SanctionedAddress",
50 "type": "event"
51 },
52 {
53 "anonymous": false,
54 "inputs": [
55 {
56 "indexed": false,
57 "internalType": "address[]",
58 "name": "addrs",
59 "type": "address[]"
60 }
61 ],
62 "name": "SanctionedAddressesAdded",
63 "type": "event"
64 },
65 {
66 "anonymous": false,
67 "inputs": [
68 {
69 "indexed": false,
70 "internalType": "address[]",
71 "name": "addrs",
72 "type": "address[]"
73 }
74 ],
75 "name": "SanctionedAddressesRemoved",
76 "type": "event"
77 },
78 {
79 "inputs": [
80 {
81 "internalType": "address[]",
82 "name": "newSanctions",
83 "type": "address[]"
84 }
85 ],
86 "name": "addToSanctionsList",
87 "outputs": [],
88 "stateMutability": "nonpayable",
89 "type": "function"
90 },
91 {
92 "inputs": [
93 {
94 "internalType": "address",
95 "name": "addr",
96 "type": "address"
97 }
98 ],
99 "name": "isSanctioned",
100 "outputs": [
101 {
102 "internalType": "bool",
103 "name": "",
104 "type": "bool"
105 }
106 ],
107 "stateMutability": "view",
108 "type": "function"
109 },
110 {
111 "inputs": [
112 {
113 "internalType": "address",
114 "name": "addr",
115 "type": "address"
116 }
117 ],
118 "name": "isSanctionedVerbose",
119 "outputs": [
120 {
121 "internalType": "bool",
122 "name": "",
123 "type": "bool"
124 }
125 ],
126 "stateMutability": "nonpayable",
127 "type": "function"
128 },
129 {
130 "inputs": [],
131 "name": "name",
132 "outputs": [
133 {
134 "internalType": "string",
135 "name": "",
136 "type": "string"
137 }
138 ],
139 "stateMutability": "pure",
140 "type": "function"
141 },
142 {
143 "inputs": [],
144 "name": "owner",
145 "outputs": [
146 {
147 "internalType": "address",
148 "name": "",
149 "type": "address"
150 }
151 ],
152 "stateMutability": "view",
153 "type": "function"
154 },
155 {
156 "inputs": [
157 {
158 "internalType": "address[]",
159 "name": "removeSanctions",
160 "type": "address[]"
161 }
162 ],
163 "name": "removeFromSanctionsList",
164 "outputs": [],
165 "stateMutability": "nonpayable",
166 "type": "function"
167 },
168 {
169 "inputs": [],
170 "name": "renounceOwnership",
171 "outputs": [],
172 "stateMutability": "nonpayable",
173 "type": "function"
174 },
175 {
176 "inputs": [
177 {
178 "internalType": "address",
179 "name": "newOwner",
180 "type": "address"
181 }
182 ],
183 "name": "transferOwnership",
184 "outputs": [],
185 "stateMutability": "nonpayable",
186 "type": "function"
187 }
188]