Hi @M.K
so we have the address array which stores all of the addresses of the wallet owner. Lets say we have 3 owners in this array like you have. So one of the conditions we want in our smart contract is that only a wallet owner can create a transaction for example. If we only had one owner this would be very simple. We would just use in the onlyOwners modifier
require(owner = msg.sender);
and then in our create transaction function we would include
function createTransaction(...arguments) public OnlyOwners {...
however since we have multipe wallet owners in this case this will not work. we need to check all of the members in the address owner array to see if the transaction is being created by one of them. if the transaction is not being created by one of the owners then we want our create transfer function to revert and not run. This is where the for loop comes in. Think of a for loop as just a way of checking all of the elements in a list. Every for loop takes in a loop variable whos value is equal to that of the current element of the list.
So say we have a list that consists of 5 numbers. Now you cant do this in solidity but say you want to print out this loops contents. One way to do it would be this (Code below is just pusdeo code style not language specific)(You cannot print like this in solidity FYI)
for (int i = 0; i < 5; i++)
{
print( i)
{
when our program is running and it gets to this loop it runs the loop for as many times as specified by the conditions inside the braket. So in this case the loop will get run 6 times (6 times as i starts at 0 so 0 ,1 ,2 ,3, 4, 5). In the first iteration i = 0 and the print function is executed for i = 0; then since i < 5 the loop starts again. and because we specify i++ (which is just i = i + 1) i is no 1 and the loop runs with i as 1. Thus the print statment gets returned for i =1, this proccess continues non stop until i becomes 6. When i becomes 6 the loop condition is no longer satisfied because 6 is not smaller or equal than 5. thus the loop ends and the program proceeds to whatever code is after the loop.
So going back to this example. we want to check if any of the addresses in our address is in fact the owner. So we make a loop going from 0 to owners.length which is just the length of our array (we want to check the full thing of course so this is a way of doing it). Then the bool owner = false. Say the owner is the last person in the array. for the first iteration i = 0 and checks the first address which is not the owner thus i gets incremented and the loop runs again for i = 1, we check the middle element and it is also not the owner. i gets incremented and the loop runs for the final time where i = 2 and checks the 3rd address and this is the owner so bool owner = true and now the loop is complete and now that owner = true our require statement is met. If perchance the owner was at the first index in the array the loop would still run even though we found the owner because the loop statment specifies it to.
If you wanted to get more advanced to save computation you could check if the owner has been found and then include a break to prevent the checking of needless checks. However if your curious about this you could look up that yourself.
So lastly in regards to your code it will not work because i is just a placeholder uint variable. Meaning it has not been assigned to anything. So when you call
if(owners[i] == msg.sender){
you will get an error because i has no defined value yet it needs to be assigned to something. Also say you had of set i to 0. It still would not work because you would only be doing one check more specifically checking the 0th or first element of the array. there would still be two other addresses that could possibly be the owner. So that is why you need the loop so that these other checks can be done.
I hope that helps in some way.
EDIT***
If the whole modifiers thing is confusing you could just include the code in the modifier directly into the functions you want to use it in, namely the createTransfer function here. Then remove the onlyOwners part from the function statment.